/** Adding the item value using Material Chips added on auto complete box */
  protected boolean addItem(final Suggestion suggestion) {
    if (getLimit() > 0) {
      if (suggestionMap.size() >= getLimit()) {
        return false;
      }
    }

    if (suggestionMap.containsKey(suggestion)) {
      return false;
    }

    final MaterialChip chip = chipProvider.getChip(suggestion);
    if (chip == null) {
      return false;
    }

    final ListItem displayItem = new ListItem();
    displayItem.setStyleName("multiValueSuggestBox-token");

    chip.setIconType(IconType.CLOSE);
    chip.addClickHandler(
        new ClickHandler() {
          public void onClick(ClickEvent clickEvent) {
            if (itemsHighlighted.contains(displayItem)) {
              chip.removeStyleName("blue white-text");
              itemsHighlighted.remove(displayItem);
            } else {
              chip.addStyleName("blue white-text");
              itemsHighlighted.add(displayItem);
            }
          }
        });

    chip.getIcon()
        .addClickHandler(
            new ClickHandler() {
              public void onClick(ClickEvent clickEvent) {
                suggestionMap.remove(suggestion);
                list.remove(displayItem);
              }
            });

    suggestionMap.put(suggestion, chip);
    displayItem.add(chip);
    list.insert(displayItem, list.getWidgetCount() - 1);
    return true;
  }
  /** Generate and build the List Items to be set on Auto Complete box. */
  private void generateAutoComplete(SuggestOracle suggestions) {
    list.setStyleName("multiValueSuggestBox-list");
    this.suggestions = suggestions;
    final ListItem item = new ListItem();

    item.setStyleName("multiValueSuggestBox-input-token");
    final SuggestBox box = new SuggestBox(suggestions, itemBox);
    String autocompleteId = DOM.createUniqueId();
    itemBox.getElement().setId(autocompleteId);

    item.add(box);
    list.add(item);

    itemBox.addKeyDownHandler(
        new KeyDownHandler() {
          public void onKeyDown(KeyDownEvent event) {
            boolean itemsChanged = false;

            switch (event.getNativeKeyCode()) {
              case KeyCodes.KEY_ENTER:
                if (directInputAllowed) {
                  String value = itemBox.getValue();
                  if (value != null && !(value = value.trim()).isEmpty()) {
                    gwt.material.design.client.base.Suggestion directInput =
                        new gwt.material.design.client.base.Suggestion();
                    directInput.setDisplay(value);
                    directInput.setSuggestion(value);
                    itemsChanged = addItem(directInput);
                    itemBox.setValue("");
                    itemBox.setFocus(true);
                  }
                }
                break;

              case KeyCodes.KEY_BACKSPACE:
                if (itemBox.getValue().trim().isEmpty()) {
                  if (itemsHighlighted.isEmpty()) {
                    if (suggestionMap.size() > 0) {

                      ListItem li = (ListItem) list.getWidget(list.getWidgetCount() - 2);
                      MaterialChip p = (MaterialChip) li.getWidget(0);

                      Set<Entry<Suggestion, MaterialChip>> entrySet = suggestionMap.entrySet();
                      for (Entry<Suggestion, MaterialChip> entry : entrySet) {
                        if (p.equals(entry.getValue())) {
                          suggestionMap.remove(entry.getKey());
                          itemsChanged = true;
                          break;
                        }
                      }

                      list.remove(li);
                    }
                  }
                }

              case KeyCodes.KEY_DELETE:
                if (itemBox.getValue().trim().isEmpty()) {
                  for (ListItem li : itemsHighlighted) {
                    li.removeFromParent();
                    MaterialChip p = (MaterialChip) li.getWidget(0);

                    Set<Entry<Suggestion, MaterialChip>> entrySet = suggestionMap.entrySet();
                    for (Entry<Suggestion, MaterialChip> entry : entrySet) {
                      if (p.equals(entry.getValue())) {
                        suggestionMap.remove(entry.getKey());
                        itemsChanged = true;
                        break;
                      }
                    }
                  }
                  itemsHighlighted.clear();
                }
                itemBox.setFocus(true);
                break;
            }

            if (itemsChanged) {
              ValueChangeEvent.fire(MaterialAutoComplete.this, getValue());
            }
          }
        });

    itemBox.addClickHandler(
        new ClickHandler() {
          @Override
          public void onClick(ClickEvent event) {
            box.showSuggestionList();
          }
        });

    box.addSelectionHandler(
        new SelectionHandler<SuggestOracle.Suggestion>() {
          public void onSelection(SelectionEvent<SuggestOracle.Suggestion> selectionEvent) {
            Suggestion selectedItem = selectionEvent.getSelectedItem();
            itemBox.setValue("");
            if (addItem(selectedItem)) {
              ValueChangeEvent.fire(MaterialAutoComplete.this, getValue());
            }
            itemBox.setFocus(true);
          }
        });

    panel.add(list);
    panel
        .getElement()
        .setAttribute("onclick", "document.getElementById('" + autocompleteId + "').focus()");
    panel.add(lblError);
    box.setFocus(true);
  }