/**
   * Get the people from the server, convert them to JSON, and feed them back to the handler.
   *
   * @param ntids the ntids.
   * @param callbackIndex the callback index.
   */
  public static void bulkGetPeople(final String[] ntids, final int callbackIndex) {
    Session.getInstance()
        .getEventBus()
        .addObserver(
            GotBulkEntityResponseEvent.class,
            new Observer<GotBulkEntityResponseEvent>() {
              public void update(final GotBulkEntityResponseEvent arg1) {
                List<String> ntidList = Arrays.asList(ntids);
                JsArray<JavaScriptObject> personJSONArray =
                    (JsArray<JavaScriptObject>) JavaScriptObject.createArray();
                int count = 0;

                if (ntidList.size() == arg1.getResponse().size()) {
                  boolean notCorrectResponse = false;
                  for (Serializable person : arg1.getResponse()) {
                    PersonModelView personMV = (PersonModelView) person;
                    if (ntidList.contains(personMV.getAccountId())) {
                      AvatarUrlGenerator urlGen = new AvatarUrlGenerator(EntityType.PERSON);
                      String imageUrl =
                          urlGen.getSmallAvatarUrl(personMV.getId(), personMV.getAvatarId());

                      JsArrayString personJSON = (JsArrayString) JavaScriptObject.createObject();
                      personJSON.set(0, personMV.getAccountId());
                      personJSON.set(1, personMV.getDisplayName());
                      personJSON.set(2, imageUrl);

                      personJSONArray.set(count, personJSON);
                      count++;
                    } else {
                      notCorrectResponse = true;
                      break;
                    }
                  }
                  if (!notCorrectResponse) {
                    callGotBulkPeopleCallback(personJSONArray, callbackIndex);
                  }
                }
              }
            });

    ArrayList<StreamEntityDTO> entities = new ArrayList<StreamEntityDTO>();

    for (int i = 0; i < ntids.length; i++) {
      StreamEntityDTO dto = new StreamEntityDTO();
      dto.setUniqueIdentifier(ntids[i]);
      dto.setType(EntityType.PERSON);
      entities.add(dto);
    }

    if (ntids.length == 0) {
      JsArray<JavaScriptObject> personJSONArray =
          (JsArray<JavaScriptObject>) JavaScriptObject.createArray();
      callGotBulkPeopleCallback(personJSONArray, callbackIndex);
    } else {
      BulkEntityModel.getInstance().fetch(entities, false);
    }
  }
  /**
   * This method takes the activity and gets a list of all the org coordinators who are responsible
   * for the person or group to whose stream the activity was posted. Those will be the recipients.
   *
   * <p>{@inheritDoc}
   */
  @Override
  public Collection<NotificationDTO> translate(
      final long inActorId, final long inDestinationId, final long inActivityId) {
    // Get the activity
    ActivityDTO activity = activitiesMapper.execute(inActivityId, null);
    StreamEntityDTO stream = activity.getDestinationStream();
    NotificationType type =
        EntityType.PERSON == stream.getType()
            ? NotificationType.FLAG_PERSONAL_ACTIVITY
            : NotificationType.FLAG_GROUP_ACTIVITY;

    // Get the list of coordinators for the org which owns the entity (person/group) in whose stream
    // the activity
    // was posted
    List<Long> coordinatorIds =
        new ArrayList<Long>(coordinatorMapper.execute(activity.getRecipientParentOrgId()));

    NotificationDTO notif = new NotificationDTO(coordinatorIds, type, inActorId);
    notif.setDestination(activity.getRecipientParentOrgId(), EntityType.ORGANIZATION);
    notif.setActivity(inActivityId, activity.getBaseObjectType());

    return Collections.singletonList(notif);
  }
  /**
   * Default constructor.
   *
   * @param json the id of the default view.
   */
  public StreamListFormElement(final JSONObject json) {
    scopes =
        new StreamScopeFormElement(
            "scopes",
            new LinkedList<StreamScope>(),
            "",
            "Enter the name of an employee or group.",
            false,
            true,
            "/resources/autocomplete/entities/",
            MAX_NAME,
            MAX_ITEMS);

    this.addStyleName(StaticResourceBundle.INSTANCE.coreCss().streamLists());
    label.addStyleName(StaticResourceBundle.INSTANCE.coreCss().formLabel());
    this.add(label);

    this.add(streamOptions);

    streamOptions.addItem("Everyone", "");
    streamOptions.addItem("Following", StreamJsonRequestFactory.FOLLOWED_BY_KEY);
    streamOptions.addItem("Saved", StreamJsonRequestFactory.SAVED_KEY);
    streamOptions.addItem("Groups I've Joined", StreamJsonRequestFactory.JOINED_GROUPS_KEY);
    streamOptions.addItem("Posted To", StreamJsonRequestFactory.RECIPIENT_KEY);
    streamOptions.addItem("Authored By", StreamJsonRequestFactory.AUTHOR_KEY);
    streamOptions.addItem("Liked By", StreamJsonRequestFactory.LIKER_KEY);

    streamOptions.addChangeHandler(
        new ChangeHandler() {
          public void onChange(final ChangeEvent event) {
            scopes.setVisible(hasStreamScopes(getSelected()));
          }
        });

    if (json == null) {
      streamOptions.setSelectedIndex(0);
      scopes.setVisible(false);
    } else {
      if (json.containsKey(StreamJsonRequestFactory.RECIPIENT_KEY)) {
        setSelectedByValue(StreamJsonRequestFactory.RECIPIENT_KEY);
      } else if (json.containsKey(StreamJsonRequestFactory.SAVED_KEY)) {
        setSelectedByValue(StreamJsonRequestFactory.SAVED_KEY);
      } else if (json.containsKey(StreamJsonRequestFactory.PARENT_ORG_KEY)) {
        setSelectedByValue(StreamJsonRequestFactory.PARENT_ORG_KEY);
      } else if (json.containsKey(StreamJsonRequestFactory.FOLLOWED_BY_KEY)) {
        setSelectedByValue(StreamJsonRequestFactory.FOLLOWED_BY_KEY);
      } else if (json.containsKey(StreamJsonRequestFactory.AUTHOR_KEY)) {
        setSelectedByValue(StreamJsonRequestFactory.AUTHOR_KEY);
      } else if (json.containsKey(StreamJsonRequestFactory.LIKER_KEY)) {
        setSelectedByValue(StreamJsonRequestFactory.LIKER_KEY);
      } else if (json.containsKey(StreamJsonRequestFactory.JOINED_GROUPS_KEY)) {
        setSelectedByValue(StreamJsonRequestFactory.JOINED_GROUPS_KEY);
      } else {
        setSelectedByValue("");
      }

      if (hasStreamScopes(getSelected())) {
        Session.getInstance()
            .getEventBus()
            .addObserver(
                GotBulkEntityResponseEvent.class,
                new Observer<GotBulkEntityResponseEvent>() {
                  public void update(final GotBulkEntityResponseEvent event) {
                    JSONArray recipientArray = json.get(getSelected()).isArray();

                    for (int i = 0; i < recipientArray.size(); i++) {
                      JSONObject recipient = (JSONObject) recipientArray.get(i);
                      String uniqueId =
                          recipient
                              .get(StreamJsonRequestFactory.ENTITY_UNIQUE_ID_KEY)
                              .isString()
                              .stringValue();
                      String displayName =
                          getEntityDisplayName(
                              EntityType.valueOf(
                                  recipient
                                      .get(StreamJsonRequestFactory.ENTITY_TYPE_KEY)
                                      .isString()
                                      .stringValue()),
                              uniqueId,
                              event.getResponse());

                      ScopeType scopeType =
                          ScopeType.valueOf(
                              recipient
                                  .get(StreamJsonRequestFactory.ENTITY_TYPE_KEY)
                                  .isString()
                                  .stringValue());

                      StreamScope scope = new StreamScope(scopeType, uniqueId);
                      scope.setDisplayName(displayName);

                      Session.getInstance()
                          .getEventBus()
                          .notifyObservers(new StreamScopeAddedEvent(scope));
                    }

                    Session.getInstance()
                        .getEventBus()
                        .removeObserver(GotBulkEntityResponseEvent.class, this);
                  }
                });

        ArrayList<StreamEntityDTO> entities = new ArrayList<StreamEntityDTO>();

        JSONArray recipientArray = json.get(getSelected()).isArray();
        for (int i = 0; i < recipientArray.size(); i++) {
          JSONObject recipient = (JSONObject) recipientArray.get(i);
          StreamEntityDTO entity = new StreamEntityDTO();
          entity.setType(
              EntityType.valueOf(
                  recipient
                      .get(StreamJsonRequestFactory.ENTITY_TYPE_KEY)
                      .isString()
                      .stringValue()));
          entity.setUniqueIdentifier(
              recipient
                  .get(StreamJsonRequestFactory.ENTITY_UNIQUE_ID_KEY)
                  .isString()
                  .stringValue());
          entities.add(entity);
        }
        BulkEntityModel.getInstance().fetch(entities, false);
      }
    }

    this.add(scopes);
  }