docs: function (options)
          {
              var self = this;
  
              self.options = $.extend({}, defaultOptions, options);
              // When itemValue is set, freeInput should always be false
  
              if (self.objectItems)
              {
                  if (self.options.freeInput === true)
                  {
                      self.options.freeInput = true;
                  }
                  else{
                      self.options.freeInput = false
                  }
              }
  
              makeOptionItemFunction(self.options, 'itemValue');
              makeOptionItemFunction(self.options, 'itemText');
              makeOptionFunction(self.options, 'tagClass');
  
              // Typeahead.js
              if (self.options.typeaheadjs)
              {
                  var typeaheadConfig   = null;
                  var typeaheadDatasets = {};
  
                  // Determine if main configurations were passed or simply a dataset
                  var typeaheadjs = self.options.typeaheadjs;
                  if ($.isArray(typeaheadjs))
                  {
                      typeaheadConfig   = typeaheadjs[0];
                      typeaheadDatasets = typeaheadjs[1];
                  }
                  else
                  {
                      typeaheadDatasets = typeaheadjs;
                  }
  
                  self.$input.typeahead(typeaheadConfig, typeaheadDatasets).on('typeahead:selected', $.proxy(function (obj, datum)
                  {
                      if (typeaheadDatasets.valueKey)
                      {
                          self.add(datum[typeaheadDatasets.valueKey]);
                      }
                      else
                      {
                          self.add(datum);
                      }
                      self.$input.typeahead('val', '');
                  }, self));
              }
  
              self.$container.on('click', $.proxy(function (event)
              {
                  if (!self.$element.attr('disabled'))
                  {
                      self.$input.removeAttr('disabled');
                  }
                  self.$input.focus();
              }, self));
  
              if (self.options.addOnBlur && self.options.freeInput)
              {
                  self.$input.on('focusout', $.proxy(function (event)
                  {
                      self.add(self.$input.val());
                      self.$input.val('');
  
                  }, self));
              }
  
              self.$container.on('keydown', 'input', $.proxy(function (event)
              {
                  var $input        = $(event.target),
                      $inputWrapper = self.findInputWrapper();
  
                  if (self.$element.attr('disabled'))
                  {
                      self.$input.attr('disabled', 'disabled');
                      return;
                  }
  
                  switch (event.which)
                  {
                      // BACKSPACE
                      case 8:
                          if (self.options.deleteTagsOnBackspace && doGetCaretPosition($input[0]) === 0)
                          {
                              var prev = $inputWrapper.prev();
                              if (prev)
                              {
                                  self.remove(prev.data('item'));
                              }
                          }
                          break;
  
                      // DELETE
                      case 46:
                          if (self.options.deleteTagsOnDeleteKey && doGetCaretPosition($input[0]) === 0)
                          {
                              var next = $inputWrapper.next();
                              if (next)
                              {
                                  self.remove(next.data('item'));
                              }
                          }
                          break;
  
                      // LEFT ARROW
                      case 37:
                          // Try to move the input before the previous tag
                          var $prevTag = $inputWrapper.prev();
                          if (self.options.MoveTagOnLeftArrow && $input.val().length === 0 && $prevTag[0])
                          {
                              $prevTag.before($inputWrapper);
                              $input.focus();
                          }
                          break;
                      // RIGHT ARROW
                      case 39:
                          // Try to move the input after the next tag
                          var $nextTag = $inputWrapper.next();
                          if (self.options.MoveTagOnRightArrow && $input.val().length === 0 && $nextTag[0])
                          {
                              $nextTag.after($inputWrapper);
                              $input.focus();
                          }
                          break;
                      default:
                      // ignore
                  }
  
                  // Reset internal input's size
                  var textLength = $input.val().length,
                      wordSpace  = Math.ceil(textLength / 5),
                      size       = textLength + wordSpace + 1;
                  $input.attr('size', Math.max(this.inputSize, $input.val().length));
              }, self));
  
              self.$container.on('keydown', 'input', $.proxy(function (event)
              {
                  var $input = $(event.target);
  
                  if (self.$element.attr('disabled'))
                  {
                      self.$input.attr('disabled', 'disabled');
                      return;
                  }
  
                  var text             = $input.val(),
                      maxLengthReached = self.options.maxChars && text.length >= self.options.maxChars;
  
                  // If not text is entered and tab event is fired shouldn't prevent the default behavior
                  if (self.options.allowTabOnEmpty && isEmpty(text) && event.which === tabKey) 
                  {
                      return;
                  }
  
                  if (self.options.freeInput && (keyCombinationInList(event, self.options.confirmKeys) || maxLengthReached))
                  {
                      self.add(maxLengthReached ? text.substr(0, self.options.maxChars) : text);
                      $input.val('');
                      (self.$input.typeahead) && self.$input.typeahead("val","");
                      event.preventDefault();
                  }
  
                  // Reset internal input's size
                  var textLength = $input.val().length,
                      wordSpace  = Math.ceil(textLength / 5),
                      size      = textLength + wordSpace + 1;
                  $input.attr('size', Math.max(this.inputSize, $input.val().length));
              }, self));
  
              // Remove icon clicked
              self.$container.on('click', '[data-role=remove]', $.proxy(function (event)
              {
                  if (self.$element.attr('disabled'))
                  {
                      return;
                  }
                  self.remove($(event.target).closest('.chip').data('item'));
              }, self));
  
              // Only add existing value as tags when using strings as tags
              if (self.options.itemValue === defaultOptions.itemValue)
              {
                  if (self.$element[0].tagName === 'INPUT')
                  {
                      self.add(self.$element.val());
                  }
              }
          }