@Override
  public void onScroll(AbsListView view, int firstVisible, int visibleCount, int totalCount) {
    if (mObjects == null) return;

    boolean loadMore = /* maybe add a padding */
        firstVisible + visibleCount >= mObjects.getTotalQueried();

    if (loadMore) {
      mLoader.cancelLoad();

      if (getActivity() instanceof Filterable) {
        Filterable context = (Filterable) getActivity();
        if (context != null) {
          List<String> filterTypes = new ArrayList<String>();
          for (int x = 0; x < context.getFilterTypes().length; x++) {
            if (context.getFilterCheckboxes()[x]) {
              Log.w(TAG, "adding " + context.getFilterTypes()[x]);
              filterTypes.add(context.getFilterTypes()[x]);
            }
          }
          mLoader =
              mObjects.queryLaterObjects(
                  getActivity(),
                  mFeedUri,
                  totalCount,
                  filterTypes.toArray(new String[filterTypes.size()]));
        }
      } else {
        mLoader = mObjects.queryLaterObjects(getActivity(), mFeedUri, totalCount, null);
      }
    }
  }
 @Override
 public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
   // the mObjects field is accessed by the ui thread as well
   if (mObjects == null) {
     mObjects = new ObjectListCursorAdapter(getActivity(), cursor);
     setListAdapter(mObjects);
   } else {
     mObjects.changeCursor(cursor);
   }
   Log.w(TAG, "setting adapter");
 }
 @Override
 public Loader<Cursor> onCreateLoader(int id, Bundle args) {
   String[] projection = new String[] {DbObject._ID};
   List<String> filterTypes = new ArrayList<String>();
   filterTypes.add(AppObj.TYPE);
   filterTypes.add(AppStateObj.TYPE);
   mLoader =
       ObjectListCursorAdapter.queryObjects(
           getActivity(),
           mFeedUri,
           projection,
           filterTypes.toArray(new String[filterTypes.size()]));
   return mLoader;
 }
  @Override
  public void onDestroy() {
    super.onDestroy();

    if (mLoader != null) {
      mLoader.cancelLoad();
    }

    // the mObjects field is accessed by the background loader
    synchronized (this) {
      if (mObjects != null) {
        ((ObjectListCursorAdapter) mObjects).closeCursor();
      }
    }
  }
  void showMenuForObj(int position) {
    // this first cursor is the internal one
    Cursor cursor = (Cursor) mObjects.getItem(position);
    long objId = cursor.getLong(0);

    DbObj obj = App.instance().getMusubi().objForId(objId);
    FragmentTransaction ft = getFragmentManager().beginTransaction();
    Fragment prev = getFragmentManager().findFragmentByTag("dialog");
    if (prev != null) {
      ft.remove(prev);
    }
    ft.addToBackStack(null);

    // Create and show the dialog.
    DialogFragment newFragment = ObjMenuDialogFragment.newInstance(obj);
    newFragment.show(ft, "dialog");
  }