public void appendExtraEventData(
      TiUIView view, int itemIndex, int sectionIndex, String bindId, String itemId) {
    KrollDict existingData = view.getAdditionalEventData();
    if (existingData == null) {
      existingData = new KrollDict();
      view.setAdditionalEventData(existingData);
    }

    // itemIndex = realItemIndex + header (if exists). We want the real item index.
    if (headerTitle != null || headerView != null) {
      itemIndex -= 1;
    }

    existingData.put(TiC.PROPERTY_SECTION, this);
    existingData.put(TiC.PROPERTY_SECTION_INDEX, sectionIndex);
    existingData.put(TiC.PROPERTY_ITEM_INDEX, itemIndex);

    if (!bindId.startsWith(TiListViewTemplate.GENERATED_BINDING)
        && !bindId.equals(TiC.PROPERTY_PROPERTIES)) {
      existingData.put(TiC.PROPERTY_BIND_ID, bindId);
    } else if (existingData.containsKey(TiC.PROPERTY_BIND_ID)) {
      existingData.remove(TiC.PROPERTY_BIND_ID);
    }

    if (itemId != null) {
      existingData.put(TiC.PROPERTY_ITEM_ID, itemId);
    } else if (existingData.containsKey(TiC.PROPERTY_ITEM_ID)) {
      existingData.remove(TiC.PROPERTY_ITEM_ID);
    }
  }
  @Override
  public void processProperties(KrollDict d) {
    if (d.get(TiC.PROPERTY_BUTTON_NAMES) != null && d.containsKey(TiC.PROPERTY_OK)) {
      d.remove(TiC.PROPERTY_OK);
    }

    if (d.get(TiC.PROPERTY_CUSTOM_VIEW) != null && d.containsKey(TiC.PROPERTY_OPTIONS)) {
      d.remove(TiC.PROPERTY_OPTIONS);
    }
    super.processProperties(d);
  }
  private void processData(Object[] items, int offset) {
    if (listItemData == null) {
      return;
    }

    TiListViewTemplate[] temps = new TiListViewTemplate[items.length];
    // First pass through data, we process template and update
    // default properties based data given
    for (int i = 0; i < items.length; i++) {
      Object itemData = items[i];
      if (itemData instanceof HashMap) {
        KrollDict d = new KrollDict((HashMap) itemData);
        TiListViewTemplate template = processTemplate(d, i + offset);
        template.updateOrMergeWithDefaultProperties(d, true);
        temps[i] = template;
      }
    }
    // Second pass we would merge properties
    for (int i = 0; i < items.length; i++) {
      Object itemData = items[i];
      if (itemData instanceof HashMap) {
        KrollDict d = new KrollDict((HashMap) itemData);
        TiListViewTemplate template = temps[i];
        if (template != null) {
          template.updateOrMergeWithDefaultProperties(d, false);
        }
        ListItemData itemD = new ListItemData(d, template);
        d.remove(TiC.PROPERTY_TEMPLATE);
        listItemData.add(i + offset, itemD);
      }
    }
    // Notify adapter that data has changed.
    adapter.notifyDataSetChanged();
  }
  private KrollDict filterProperties(KrollDict d) {
    if (d == null) return new KrollDict();

    KrollDict filtered = new KrollDict(d);
    for (int i = 0; i < filteredProperties.length; i++) {
      if (filtered.containsKey(filteredProperties[i])) {
        filtered.remove(filteredProperties[i]);
      }
    }
    return filtered;
  }
 @Override
 public void handleCreationDict(KrollDict dict) {
   Object data[] = null;
   if (dict.containsKey(TiC.PROPERTY_DATA)) {
     Object o = dict.get(TiC.PROPERTY_DATA);
     if (o != null && o instanceof Object[]) {
       data = (Object[]) o;
       dict.remove(TiC.PROPERTY_DATA); // don't override our data accessor
     }
   }
   super.handleCreationDict(dict);
   if (data != null) {
     processData(data);
   }
 }