int fields_count = 0;
 
 list_item *database = NULL;
-int items = 0;
+static int items = 0;
 
 #define ITEM_SIZE (fields_count * sizeof(char *))
+#define LAST_ITEM (items - 1)
 
 #define INITIAL_LIST_CAPACITY  30
 static int list_capacity = 0;
        return item <= LAST_ITEM && item >= 0;
 }
 
+int
+last_item()
+{
+       return LAST_ITEM;
+}
+
+int
+db_n_items()
+{
+       return items;
+}
 
 int
 real_db_enumerate_items(struct db_enumerator e)
 
 int find_item(char *str, int start, int search_fields[]);
 int is_selected(int item);
 int is_valid_item(int item);
+int last_item();
+int db_n_items();
 
 int real_db_enumerate_items(struct db_enumerator e);
 struct db_enumerator init_db_enumerator(int mode);
  * Various macros
  */
 
-#define LAST_ITEM (items - 1)
-
 #define have_multiple_emails(item) \
        strchr(db_email_get(item), ',')
 
 
  * some extern variables
  */
 
-
-extern int curitem;
 extern int views_count;
-extern int items;
 
 WINDOW *editw;
 
 void
 edit_item(int item)
 {
-       if( item < 0 ) {
-               if( curitem < 0 )
+       if(item < 0) {
+               if(list_get_curitem() < 0)
                        return;
                else
-                       item = curitem;
+                       item = list_get_curitem();
        }
 
        init_editor();
 
        while((item = edit_loop(item)) >= 0)
-               curitem = item; /* hmm, this is not very clean way to go */
+               list_set_curitem(item); /* this is not very clean way to go */
 
        close_editor();
 }
        add_item2database(item);
        item_free(&item);
 
-       curitem = LAST_ITEM;
+       list_set_curitem(last_item());
 
-       edit_item(LAST_ITEM);
+       edit_item(last_item());
 }
 
 
 #include "xmalloc.h"
 #include <assert.h>
 
-extern int items;
 extern abook_field_list *fields_list;
 extern int fields_count;
 
 {
        int filter;
        char *filename;
-       int tmp = items;
+       int tmp = db_n_items();
 
        import_screen();
 
 
        if(i_read_file(filename, i_filters[filter].func ))
                statusline_msg(_("Error occured while opening the file"));
-       else if(tmp == items)
+       else if(tmp == db_n_items())
                statusline_msg(_("File does not seem to be a valid addressbook"));
 
        refresh_screen();
 import_file(char filtname[FILTNAME_LEN], char *filename)
 {
        int i;
-       int tmp = items;
+       int tmp = db_n_items();
        int ret = 0;
 
        for(i=0;; i++) {
        } else
                ret =  i_read_file(filename, i_filters[i].func);
 
-       if(tmp == items)
+       if(tmp == db_n_items())
                ret = 1;
 
        return ret;
        char tmp[MAX_EMAILSTR_LEN];
        int extra_column;
 
-       if(items < 1)
+       if(list_is_empty())
                return 2;
 
        extra_column = init_extra_field(STR_EXTRA_COLUMN);
 
 int extra_column = -1;
 int extra_alternative = -1;
 
-extern int items;
 extern abook_field_list *fields_list;
 
 static WINDOW *list = NULL;
        else if(curitem > LAST_LIST_ITEM)
                first_list_item = max(curitem - LIST_LINES + 1, 0);
 
-        for( line = 0, i = first_list_item ; i <= LAST_LIST_ITEM && i < items;
-                       line++, i++ ) {
+        for(line = 0, i = first_list_item;
+                       i <= LAST_LIST_ITEM && i < db_n_items();
+                       line++, i++) {
 
                print_list_line(i, line, i == curitem);
         }
 void
 scroll_down()
 {
-       if(curitem > items - 2)
+       if(curitem > db_n_items() - 2)
                return;
 
        curitem++;
 void
 page_down()
 {
-       if(curitem > items - 2)
+       if(curitem > db_n_items() - 2)
                return;
 
-       curitem = curitem == LAST_LIST_ITEM ?
-               ((curitem += LIST_LINES) > LAST_ITEM ? LAST_ITEM : curitem) :
-               min(LAST_LIST_ITEM, LAST_ITEM);
+       if(curitem == LAST_LIST_ITEM) {
+               if((curitem += LIST_LINES) > last_item())
+                       curitem = last_item();
+       } else {
+               curitem = min(LAST_LIST_ITEM, last_item());
+       }
 
        refresh_list();
 }
 void
 select_none()
 {
-        memset(selected, 0, items);
+        memset(selected, 0, db_n_items());
 }
 
 void
 select_all()
 {
-        memset(selected, 1, items);
+        memset(selected, 1, db_n_items());
+}
+
+void
+list_set_selection(int item, int value)
+{
+       assert(is_valid_item(item));
+
+       selected[item] = !!value;
+}
+
+void
+list_invert_curitem_selection()
+{
+       assert(is_valid_item(curitem));
+
+       selected[curitem] = !selected[curitem];
 }
 
 void
 {
         list_item tmp;
 
-        if( curitem < 0 || curitem > LAST_ITEM )
+        if(curitem < 0 || curitem > last_item())
                 return;
 
        tmp = item_create();
                        break;
 
                case MOVE_ITEM_DOWN:
-                       if( curitem >= LAST_ITEM )
+                       if(curitem >= last_item())
                                goto out_move;
                        item_copy(db_item_get(curitem),
                                        db_item_get(curitem + 1));
 void
 goto_home()
 {
-       if(items > 0)
+       if(db_n_items() > 0)
                curitem = 0;
 
        refresh_list();
 void
 goto_end()
 {
-       if(items > 0)
-               curitem = LAST_ITEM;
+       if(db_n_items() > 0)
+               curitem = last_item();
 
        refresh_list();
 }
 {
        int i, n = 0;
 
-       for(i = 0; i < items; i++)
+       for(i = 0; i < db_n_items(); i++)
                if(selected[i])
                        n++;
 
 {
        int i;
 
-       if(items < 1)
+       if(list_is_empty())
                return;
 
-       for(i = 0; i < items; i++)
+       for(i = 0; i < db_n_items(); i++)
                selected[i] = !selected[i];
 }
 
 int
-list_current_item()
+list_is_empty()
 {
-       return curitem;
+       return db_n_items() < 1;
 }
 
 int
-list_is_empty()
+list_get_curitem()
+{
+       return curitem;
+}
+
+void
+list_set_curitem(int i)
 {
-       return items < 1;
+       curitem = i;
 }
 
 int
        }
        item_free(&item);
 
-       curitem = LAST_ITEM;
+       curitem = last_item();
        refresh_list();
 
        return 0;
 
 void           page_down();
 void            select_none();
 void            select_all();
+void           set_selection(int item, int value);
+void           list_invert_curitem_selection();
 void            move_curitem(int direction);
 void           goto_home();
 void           goto_end();
 void           highlight_line(WINDOW *win, int line);
 int            selected_items();
 void           invert_selection();
-int            list_current_item();
 int            list_is_empty();
+int            list_get_curitem();
+void           list_set_curitem(int i);
 int            duplicate_item();
 
 
 #define EMAILLEN        (EXTRAPOS - EMAILPOS - 1)
 #define EXTRALEN       (COLS - EXTRAPOS)
 
-#define LAST_LIST_ITEM ( first_list_item + LIST_LINES - 1 )
+#define LAST_LIST_ITEM (first_list_item + LIST_LINES - 1)
 
 #endif
 
  * external variables
  */
 
-extern int curitem;
-extern int items;
 extern char *datafile;
 
 extern bool alternative_datafile;
  */
 
 extern char *selected;
-extern int curitem;
 
 void
 get_commands()
                        case 'q': return;
                        case 'Q': quit_abook(QUIT_DONTSAVE);    break;
                        case 'P': print_stderr(selected_items() ?
-                                                 -1 : list_current_item());
+                                                 -1 : list_get_curitem());
                                  return;
                        case '?':
                                  display_help(HELP_MAIN);
                        case '/': ui_find(0);           break;
                        case '\\': ui_find(1);          break;
 
-                       case ' ': if(curitem >= 0) {
-                                  selected[curitem] = !selected[curitem];
+                       case ' ': if(list_get_curitem() >= 0) {
+                                  list_invert_curitem_selection();
                                   ui_print_number_of_items();
                                   refresh_list();
                                  }
                                break;
 
                        case 'm': launch_mutt(selected_items() ?
-                                                 -1 : list_current_item());
+                                                 -1 : list_get_curitem());
                                  refresh_screen();
                                  break;
 
                        case 'p': ui_print_database(); break;
 
-                       case 'v': launch_wwwbrowser(list_current_item());
+                       case 'v': launch_wwwbrowser(list_get_curitem());
                                  refresh_screen();
                                  break;
                }
                refresh_screen();
        }
 
-       if( (item = find_item(findstr, curitem + !!next, search_fields)) < 0 &&
+       if( (item = find_item(findstr, list_get_curitem() + !!next,
+                       search_fields)) < 0 &&
                        (item = find_item(findstr, 0, search_fields)) >= 0)
                statusline_addstr(_("Search hit bottom, continuing at top"));
 
        if(item >= 0) {
-               curitem = item;
+               list_set_curitem(item);
                refresh_list();
        }
 }
 void
 ui_print_number_of_items()
 {
-       char *str = strdup_printf("     " "|%3d/%3d", selected_items(), items);
+       char *str = strdup_printf("     " "|%3d/%3d",
+               selected_items(), db_n_items());
 
        mvaddstr(0, COLS-strlen(str), str);
 
 {
        char *msg;
 
-       if(items > 0) {
+       if(!list_is_empty()) {
                msg = strdup_printf(_("Your current data will be lost - "
                                "Press '%c' to continue"),
                                *(S_("keybinding for yes|y")));
 
        load_database(filename);
 
-       if(items == 0) {
+       if(list_is_empty()) {
                statusline_msg(_("Sorry, the specified file appears not to be a valid abook addressbook"));
                load_database(datafile);
        } else {