@Override
  public PFQuery<PAPUser> getQuery() {
    // Use cached facebook friend ids
    List<String> facebookFriends = PAPCache.getSharedCache().getFacebookFriends();

    // Query for all friends you have on facebook and who are using the app
    PFQuery<PAPUser> friendsQuery = PFQuery.getQuery(PAPUser.class);
    friendsQuery.whereContainedIn(PAPUser.FACEBOOK_ID_KEY, facebookFriends);

    // Query for all Parse employees
    List<String> parseEmployees = new ArrayList<>(PARSE_EMPLOYEE_ACCOUNTS);
    parseEmployees.remove(PAPUser.getCurrentUser().getFacebookId());
    PFQuery<PAPUser> parseEmployeeQuery = PFQuery.getQuery(PAPUser.class);
    parseEmployeeQuery.whereContainedIn(PAPUser.FACEBOOK_ID_KEY, parseEmployees);

    PFQuery<PAPUser> query = PFQuery.or(new NSArray<PFQuery<?>>(friendsQuery, parseEmployeeQuery));
    query.setCachePolicy(PFCachePolicy.NetworkOnly);

    if (getObjects().size() == 0) {
      query.setCachePolicy(PFCachePolicy.CacheThenNetwork);
    }

    query.orderByAscending(PAPUser.DISPLAY_NAME_KEY);

    return query;
  }
  @Override
  public void didLoadObjects(NSError error) {
    super.didLoadObjects(error);

    PFQuery<PAPActivity> isFollowingQuery = PFQuery.getQuery(PAPActivity.class);
    isFollowingQuery.whereEqualTo(PAPActivity.FROM_USER_KEY, PAPUser.getCurrentUser());
    isFollowingQuery.whereEqualTo(PAPActivity.TYPE_KEY, PAPActivityType.FOLLOW.getKey());
    isFollowingQuery.whereContainedIn(PAPActivity.TO_USER_KEY, getObjects());
    isFollowingQuery.whereContainedIn(PAPActivity.TO_USER_KEY, getObjects());
    isFollowingQuery.setCachePolicy(PFCachePolicy.NetworkOnly);

    isFollowingQuery.countInBackground(
        new PFCountCallback() {
          @Override
          public void done(int count, NSError error) {
            NSArray<PAPUser> objects = getObjects();
            if (error == null) {
              if (count == objects.size()) {
                followStatus = PAPFindFriendsFollowStatus.ALL;
                configureUnfollowAllButton();
                for (PAPUser user : objects) {
                  PAPCache.getSharedCache().setUserFollowStatus(user, true);
                }
              } else if (count == 0) {
                followStatus = PAPFindFriendsFollowStatus.NONE;
                configureFollowAllButton();
                for (PAPUser user : objects) {
                  PAPCache.getSharedCache().setUserFollowStatus(user, false);
                }
              } else {
                followStatus = PAPFindFriendsFollowStatus.SOME;
                configureFollowAllButton();
              }
            }

            if (objects.size() == 0) {
              getNavigationItem().setRightBarButtonItem(null);
            }
          }
        });

    if (getObjects().size() == 0) {
      getNavigationItem().setRightBarButtonItem(null);
    }
  }
  @Override
  public PFTableViewCell getCellForRow(
      final UITableView tableView, final NSIndexPath indexPath, final PAPUser user) {
    final String friendCellIdentifier = "FriendCell";

    PAPFindFriendsCell cell =
        (PAPFindFriendsCell) tableView.dequeueReusableCell(friendCellIdentifier);
    if (cell == null) {
      cell = new PAPFindFriendsCell(UITableViewCellStyle.Default, friendCellIdentifier);
      cell.setDelegate(this);
    }

    cell.setUser(user);

    cell.getPhotoLabel().setText("0 photos");

    PAPUserAttributes attributes = PAPCache.getSharedCache().getUserAttributes(user);

    if (attributes != null) {
      // set them now
      int count = PAPCache.getSharedCache().getUserPhotoCount(user);
      cell.getPhotoLabel().setText(String.format("%d photo%s", count, count == 1 ? "" : "s"));
    } else {
      synchronized (this) {
        Boolean outstandingCountQueryStatus = outstandingCountQueries.get(indexPath);
        if (outstandingCountQueryStatus == null || !outstandingCountQueryStatus) {
          outstandingCountQueries.put(indexPath, true);
          PFQuery<PAPPhoto> photoNumQuery = PFQuery.getQuery(PAPPhoto.class);
          photoNumQuery.whereEqualTo(PAPPhoto.USER_KEY, user);
          photoNumQuery.setCachePolicy(PFCachePolicy.CacheThenNetwork);
          photoNumQuery.countInBackground(
              new PFCountCallback() {
                @Override
                public void done(int count, NSError error) {
                  synchronized (PAPFindFriendsViewController.this) {
                    PAPCache.getSharedCache().setUserPhotoCount(user, count);
                    outstandingCountQueries.remove(indexPath);
                  }
                  PAPFindFriendsCell actualCell =
                      (PAPFindFriendsCell) tableView.getCellForRow(indexPath);
                  actualCell
                      .getPhotoLabel()
                      .setText(String.format("%d photo%s", count, count == 1 ? "" : "s"));
                }
              });
        }
      }
    }

    cell.getFollowButton().setSelected(false);
    cell.setTag(indexPath.getRow());

    if (followStatus == PAPFindFriendsFollowStatus.SOME) {
      if (attributes != null) {
        cell.getFollowButton().setSelected(PAPCache.getSharedCache().getUserFollowStatus(user));
      } else {
        synchronized (this) {
          final PAPFindFriendsCell c = cell;

          Boolean outstandingQuery = outstandingFollowQueries.get(indexPath);
          if (outstandingQuery == null || !outstandingQuery) {
            outstandingFollowQueries.put(indexPath, true);
            PFQuery<PAPActivity> isFollowingQuery = PFQuery.getQuery(PAPActivity.class);
            isFollowingQuery.whereEqualTo(PAPActivity.FROM_USER_KEY, PAPUser.getCurrentUser());
            isFollowingQuery.whereEqualTo(PAPActivity.TYPE_KEY, PAPActivityType.FOLLOW.getKey());
            isFollowingQuery.whereEqualTo(PAPActivity.TO_USER_KEY, user);
            isFollowingQuery.setCachePolicy(PFCachePolicy.CacheThenNetwork);

            isFollowingQuery.countInBackground(
                new PFCountCallback() {
                  @Override
                  public void done(int count, NSError error) {
                    synchronized (this) {
                      outstandingFollowQueries.remove(indexPath);
                      PAPCache.getSharedCache()
                          .setUserFollowStatus(user, error == null && count > 0);
                    }
                    if (c.getTag() == indexPath.getRow()) {
                      c.getFollowButton().setSelected(error == null && count > 0);
                    }
                  }
                });
          }
        }
      }
    } else {
      cell.getFollowButton().setSelected(followStatus == PAPFindFriendsFollowStatus.ALL);
    }

    return cell;
  }