public ItemTreeItemAdapter(
      final ItemListView itemListView,
      final IOnItemCompleted onItemCompleted,
      final IOnItemNotes onItemNotes,
      final TreeStateManager<Item> treeStateManager,
      final int numberOfLevels) {
    super(itemListView, treeStateManager, numberOfLevels);

    mClient = itemListView.getClient();
    mStorage = mClient.getStorage();

    mOnItemCompleted = onItemCompleted;
    mOnItemNotes = onItemNotes;

    mItemListView = itemListView;
    mItemViewMode = mItemListView.getViewMode();
    mItemViewInQueryMode = mItemListView.getItemViewInQueryMode();
  }
  @Override
  public View updateView(final View view, final TreeNodeInfo<Item> treeNodeInfo) {
    final Item item = treeNodeInfo.getId();
    LinearLayout viewLayout = (LinearLayout) view;

    TextView itemContent = (TextView) viewLayout.findViewById(R.id.item_list_item_content);
    TextView itemLabels = (TextView) viewLayout.findViewById(R.id.item_list_item_labels);
    ImageView itemNotes = (ImageView) viewLayout.findViewById(R.id.item_list_item_notes);
    TextView itemNoteCount = (TextView) viewLayout.findViewById(R.id.item_list_item_note_count);
    ImageView itemRepeat = (ImageView) viewLayout.findViewById(R.id.item_list_item_repeat);
    TextView itemDueDate = (TextView) viewLayout.findViewById(R.id.item_list_item_due_date);
    LinearLayout itemDateLayout =
        (LinearLayout) viewLayout.findViewById(R.id.item_list_item_date_layout);
    final CheckBox itemCheckbox = (CheckBox) viewLayout.findViewById(R.id.item_list_item_checkbox);

    mTextSize = mStorage.getTextSize();
    mItemViewInQueryMode = mItemListView.getItemViewInQueryMode();

    // Display the formatted text (highlighting, etc)
    itemContent.setText(TodoistTextFormatter.formatText(item.getContent()));

    itemContent.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mTextSize);
    // Linkify any emails, web addresses and phone numbers in the item's content
    Linkify.addLinks(itemContent, Linkify.ALL);

    itemLabels.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mTextSize - 4);

    if ((mItemViewMode == ItemViewMode.FILTER_BY_LABELS)
        || ((mItemViewMode == ItemViewMode.FILTER_BY_QUERIES)
            && (mItemViewInQueryMode == ItemViewInQueryMode.PROJECTS))) {
      // Show item's projects
      Project project = mClient.getProjectById(item.projectId);

      if (project != null) {
        itemLabels.setText(project.getName());
        itemLabels.setBackgroundColor((0xFF << 24) | project.getColor());
      } else {
        // Rare case that shouldn't happen - item is pointing to an old project that no longer
        // exists
        itemLabels.setText("");
        itemLabels.setBackgroundColor((0xFF << 24) | Color.WHITE);
      }

    } else {
      itemLabels.setText("");
      itemLabels.setBackgroundColor((0x00 << 24)); // Transparent background color

      // Show item's labels
      if (item.labelIds != null) {
        // Fill out the labels
        for (int i = 0; i < item.labelIds.size(); i++) {
          int labelId = item.labelIds.get(i);
          Label currentLabel = mIdToLabels.get(labelId);

          if (currentLabel == null) {
            // Weird case when we have an ID but no matching label for it
            // TODO: What should we do other than this?
            continue;
          }

          itemLabels.append(
              Html.fromHtml(
                  String.format(
                      "<font color='#%X'><i>%s</i></font>",
                      currentLabel.getColor(), currentLabel.name)));

          if (i < item.labelIds.size() - 1) {
            itemLabels.append(", ");
          }
        }

        // Since Italic text gets cut off on "wrap_contents" TextView width
        itemLabels.append(" ");
      }
    }

    if (mClient.isPremium()) {
      itemNoteCount.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mTextSize - 7);
      if (item.noteCount > 0) {
        itemNotes.setVisibility(View.VISIBLE);
        itemNoteCount.setText(String.valueOf(item.noteCount));
        itemNoteCount.setVisibility(View.VISIBLE);
      } else {
        // No notes (don't show an icon)
        itemNotes.setVisibility(View.GONE);
        itemNoteCount.setVisibility(View.GONE);
      }

      itemNotes.setTag(item);
      itemNotes.setOnClickListener(this);

    } else {
      // Only premium users have task notes
      itemNotes.setVisibility(View.GONE);
      itemNoteCount.setVisibility(View.GONE);
    }

    // Show a "recurring" image for item if necessary
    if (item.isRecurring()) {
      itemRepeat.setVisibility(View.VISIBLE);
    } else {
      itemRepeat.setVisibility(View.GONE);
    }

    itemDueDate.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mTextSize - 4);

    if ((item.dueDate == null) || (item.dueDate.getTime() == 0)) {
      itemDateLayout.setVisibility(View.GONE);
    } else {
      itemDateLayout.setVisibility(View.VISIBLE);
      itemDueDate.setText(
          item.getDueDateDescription(
              mClient.getUser().timeFormat, mClient.getUser().timezoneOffsetMinutes));
      itemDateLayout.setBackgroundColor((0xFF << 24) | item.getDueDateColor());
    }

    itemCheckbox.setTag(item);
    itemCheckbox.setOnCheckedChangeListener(null);
    itemCheckbox.setChecked(item.completed);

    // Determine which checkbox to display according to text size
    int checkBoxDrawable;
    int checkBoxHeight;

    if (mTextSize <= 10) {
      checkBoxDrawable = R.drawable.checkbox_selector_small;
      checkBoxHeight = 16; // DP - height and width are the same
    } else if (mTextSize <= 13) {
      checkBoxDrawable = R.drawable.checkbox_selector_medium;
      checkBoxHeight = 24; // DP - height and width are the same
    } else {
      checkBoxDrawable = R.drawable.checkbox_selector_large;
      checkBoxHeight = 32; // DP - height and width are the same
    }

    // Convert from Device-Independent pixels to actual screen pixels
    int dpHeight =
        (int)
            TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_DIP,
                checkBoxHeight,
                mItemListView.getResources().getDisplayMetrics());

    // Set the checkbox image + dimensions to use
    itemCheckbox.setLayoutParams(new LinearLayout.LayoutParams(dpHeight, dpHeight));
    itemCheckbox.setButtonDrawable(checkBoxDrawable);

    if (item.completed) itemContent.setTextColor(Color.GRAY);
    else itemContent.setTextColor((0xFF << 24) | item.getItemPriorityColor());

    itemCheckbox.setOnCheckedChangeListener(onCheckedChange);

    if (!item.canBeCompleted()) {
      // Some items can be marked as non-completeable
      itemCheckbox.setVisibility(View.INVISIBLE);
    } else {
      itemCheckbox.setVisibility(View.VISIBLE);
    }

    viewLayout.setOnClickListener(
        new OnClickListener() {
          @Override
          public void onClick(View arg0) {
            if (item.canBeCompleted()) {
              itemCheckbox.setChecked(!itemCheckbox.isChecked());
            }
          }
        });
    viewLayout.setLongClickable(true);

    viewLayout.setTag(item);

    return viewLayout;
  }