text: /*
   *  Bootstrap Duallistbox - v3.0.6
   *  A responsive dual listbox widget optimized for Twitter Bootstrap. It works on all modern browsers and on touch devices.
   *  http://www.virtuosoft.eu/code/bootstrap-duallistbox/
   *
   *  Made by István Ujj-Mészáros
   *  Under Apache License v2.0 License
   */
  ;(function ($, window, document, undefined) {
    // Create the defaults once
    var pluginName = 'bootstrapDualListbox',
      defaults = {
        bootstrap2Compatible: false,
        filterTextClear: 'show all',
        filterPlaceHolder: 'Filter',
        moveSelectedLabel: 'Move selected',
        moveAllLabel: 'Move all',
        removeSelectedLabel: 'Remove selected',
        removeAllLabel: 'Remove all',
        moveOnSelect: true,                                                                 // true/false (forced true on androids, see the comment later)
        preserveSelectionOnMove: false,                                                     // 'all' / 'moved' / false
        selectedListLabel: false,                                                           // 'string', false
        nonSelectedListLabel: false,                                                        // 'string', false
        helperSelectNamePostfix: '_helper',                                                 // 'string_of_postfix' / false
        selectorMinimalHeight: 100,
        showFilterInputs: true,                                                             // whether to show filter inputs
        nonSelectedFilter: '',                                                              // string, filter the non selected options
        selectedFilter: '',                                                                 // string, filter the selected options
        infoText: 'Showing all {0}',                                                        // text when all options are visible / false for no info text
        infoTextFiltered: '<span class="label label-warning">Filtered</span> {0} from {1}', // when not all of the options are visible due to the filter
        infoTextEmpty: 'Empty list',                                                        // when there are no options present in the list
        filterOnValues: false,                                                              // filter by selector's values, boolean
        sortByInputOrder: false,
        eventMoveOverride: false,                                                           // boolean, allows user to unbind default event behaviour and run their own instead
        eventMoveAllOverride: false,                                                        // boolean, allows user to unbind default event behaviour and run their own instead
        eventRemoveOverride: false,                                                         // boolean, allows user to unbind default event behaviour and run their own instead
        eventRemoveAllOverride: false                                                       // boolean, allows user to unbind default event behaviour and run their own instead
      },
      // Selections are invisible on android if the containing select is styled with CSS
      // http://code.google.com/p/android/issues/detail?id=16922
      isBuggyAndroid = /android/i.test(navigator.userAgent.toLowerCase());
  
    // The actual plugin constructor
    function BootstrapDualListbox(element, options) {
      this.element = $(element);
      // jQuery has an extend method which merges the contents of two or
      // more objects, storing the result in the first object. The first object
      // is generally empty as we don't want to alter the default options for
      // future instances of the plugin
      this.settings = $.extend({}, defaults, options);
      this._defaults = defaults;
      this._name = pluginName;
      this.init();
    }
  
    function triggerChangeEvent(dualListbox) {
      dualListbox.element.trigger('change');
    }
  
    function updateSelectionStates(dualListbox) {
      dualListbox.element.find('option').each(function(index, item) {
        var $item = $(item);
        if (typeof($item.data('original-index')) === 'undefined') {
          $item.data('original-index', dualListbox.elementCount++);
        }
        if (typeof($item.data('_selected')) === 'undefined') {
          $item.data('_selected', false);
        }
      });
    }
  
    function changeSelectionState(dualListbox, original_index, selected) {
      dualListbox.element.find('option').each(function(index, item) {
        var $item = $(item);
        if ($item.data('original-index') === original_index) {
          $item.prop('selected', selected);
          if(selected){
            $item.attr('data-sortindex', dualListbox.sortIndex);
            dualListbox.sortIndex++;
          } else {
            $item.removeAttr('data-sortindex');
          }
        }
      });
    }
  
    function formatString(s, args) {
      return s.replace(/\{(\d+)\}/g, function(match, number) {
        return typeof args[number] !== 'undefined' ? args[number] : match;
      });
    }
  
    function refreshInfo(dualListbox) {
      if (!dualListbox.settings.infoText) {
        return;
      }
  
      var visible1 = dualListbox.elements.select1.find('option').length,
        visible2 = dualListbox.elements.select2.find('option').length,
        all1 = dualListbox.element.find('option').length - dualListbox.selectedElements,
        all2 = dualListbox.selectedElements,
        content = '';
  
      if (all1 === 0) {
        content = dualListbox.settings.infoTextEmpty;
      } else if (visible1 === all1) {
        content = formatString(dualListbox.settings.infoText, [visible1, all1]);
      } else {
        content = formatString(dualListbox.settings.infoTextFiltered, [visible1, all1]);
      }
  
      dualListbox.elements.info1.html(content);
      dualListbox.elements.box1.toggleClass('filtered', !(visible1 === all1 || all1 === 0));
  
      if (all2 === 0) {
        content = dualListbox.settings.infoTextEmpty;
      } else if (visible2 === all2) {
        content = formatString(dualListbox.settings.infoText, [visible2, all2]);
      } else {
        content = formatString(dualListbox.settings.infoTextFiltered, [visible2, all2]);
      }
  
      dualListbox.elements.info2.html(content);
      dualListbox.elements.box2.toggleClass('filtered', !(visible2 === all2 || all2 === 0));
    }
  
    function refreshSelects(dualListbox) {
      dualListbox.selectedElements = 0;
  
      dualListbox.elements.select1.empty();
      dualListbox.elements.select2.empty();
  
      dualListbox.element.find('option').each(function(index, item) {
        var $item = $(item);
        if ($item.prop('selected')) {
          dualListbox.selectedElements++;
          dualListbox.elements.select2.append($item.clone(true).prop('selected', $item.data('_selected')));
        } else {
          dualListbox.elements.select1.append($item.clone(true).prop('selected', $item.data('_selected')));
        }
      });
  
      if (dualListbox.settings.showFilterInputs) {
        filter(dualListbox, 1);
        filter(dualListbox, 2);
      }
      refreshInfo(dualListbox);
    }
  
    function filter(dualListbox, selectIndex) {
      if (!dualListbox.settings.showFilterInputs) {
        return;
      }
  
      saveSelections(dualListbox, selectIndex);
  
      dualListbox.elements['select'+selectIndex].empty().scrollTop(0);
      var regex = new RegExp($.trim(dualListbox.elements['filterInput'+selectIndex].val()), 'gi'),
        allOptions = dualListbox.element.find('option'),
        options = dualListbox.element;
  
      if (selectIndex === 1) {
        options = allOptions.not(':selected');
      } else  {
        options = options.find('option:selected');
      }
  
      options.each(function(index, item) {
        var $item = $(item),
          isFiltered = true;
        if (item.text.match(regex) || (dualListbox.settings.filterOnValues && $item.attr('value').match(regex) ) ) {
          isFiltered = false;
          dualListbox.elements['select'+selectIndex].append($item.clone(true).prop('selected', $item.data('_selected')));
        }
        allOptions.eq($item.data('original-index')).data('filtered'+selectIndex, isFiltered);
      });
  
      refreshInfo(dualListbox);
    }
  
    function saveSelections(dualListbox, selectIndex) {
      var options = dualListbox.element.find('option');
      dualListbox.elements['select'+selectIndex].find('option').each(function(index, item) {
        var $item = $(item);
        options.eq($item.data('original-index')).data('_selected', $item.prop('selected'));
      });
    }
  
    function sortOptionsByInputOrder(select){
      var selectopt = select.children('option');
  
      selectopt.sort(function(a,b){
        var an = parseInt(a.getAttribute('data-sortindex')),
            bn = parseInt(b.getAttribute('data-sortindex'));
  
            if(an > bn) {
               return 1;
            }
            if(an < bn) {
              return -1;
            }
            return 0;
      });
  
      selectopt.detach().appendTo(select);
    }
  
    function sortOptions(select) {
      select.find('option').sort(function(a, b) {
        return ($(a).data('original-index') > $(b).data('original-index')) ? 1 : -1;
      }).appendTo(select);
    }
  
    function clearSelections(dualListbox) {
      dualListbox.elements.select1.find('option').each(function() {
        dualListbox.element.find('option').data('_selected', false);
      });
    }
  
    function move(dualListbox) {
      if (dualListbox.settings.preserveSelectionOnMove === 'all' && !dualListbox.settings.moveOnSelect) {
        saveSelections(dualListbox, 1);
        saveSelections(dualListbox, 2);
      } else if (dualListbox.settings.preserveSelectionOnMove === 'moved' && !dualListbox.settings.moveOnSelect) {
        saveSelections(dualListbox, 1);
      }
  
      dualListbox.elements.select1.find('option:selected').each(function(index, item) {
        var $item = $(item);
        if (!$item.data('filtered1')) {
          changeSelectionState(dualListbox, $item.data('original-index'), true);
        }
      });
  
      refreshSelects(dualListbox);
      triggerChangeEvent(dualListbox);
      if(dualListbox.settings.sortByInputOrder){
          sortOptionsByInputOrder(dualListbox.elements.select2);
      } else {
          sortOptions(dualListbox.elements.select2);
      }
    }
  
    function remove(dualListbox) {
      if (dualListbox.settings.preserveSelectionOnMove === 'all' && !dualListbox.settings.moveOnSelect) {
        saveSelections(dualListbox, 1);
        saveSelections(dualListbox, 2);
      } else if (dualListbox.settings.preserveSelectionOnMove === 'moved' && !dualListbox.settings.moveOnSelect) {
        saveSelections(dualListbox, 2);
      }
  
      dualListbox.elements.select2.find('option:selected').each(function(index, item) {
        var $item = $(item);
        if (!$item.data('filtered2')) {
          changeSelectionState(dualListbox, $item.data('original-index'), false);
        }
      });
  
      refreshSelects(dualListbox);
      triggerChangeEvent(dualListbox);
      sortOptions(dualListbox.elements.select1);
      if(dualListbox.settings.sortByInputOrder){
          sortOptionsByInputOrder(dualListbox.elements.select2);
      }
    }
  
    function moveAll(dualListbox) {
      if (dualListbox.settings.preserveSelectionOnMove === 'all' && !dualListbox.settings.moveOnSelect) {
        saveSelections(dualListbox, 1);
        saveSelections(dualListbox, 2);
      } else if (dualListbox.settings.preserveSelectionOnMove === 'moved' && !dualListbox.settings.moveOnSelect) {
        saveSelections(dualListbox, 1);
      }
  
      dualListbox.element.find('option').each(function(index, item) {
        var $item = $(item);
        if (!$item.data('filtered1')) {
          $item.prop('selected', true);
          $item.attr('data-sortindex', dualListbox.sortIndex);
          dualListbox.sortIndex++;
        }
      });
  
      refreshSelects(dualListbox);
      triggerChangeEvent(dualListbox);
    }
  
    function removeAll(dualListbox) {
      if (dualListbox.settings.preserveSelectionOnMove === 'all' && !dualListbox.settings.moveOnSelect) {
        saveSelections(dualListbox, 1);
        saveSelections(dualListbox, 2);
      } else if (dualListbox.settings.preserveSelectionOnMove === 'moved' && !dualListbox.settings.moveOnSelect) {
        saveSelections(dualListbox, 2);
      }
  
      dualListbox.element.find('option').each(function(index, item) {
        var $item = $(item);
        if (!$item.data('filtered2')) {
          $item.prop('selected', false);
          $item.removeAttr('data-sortindex');
        }
      });
  
      refreshSelects(dualListbox);
      triggerChangeEvent(dualListbox);
    }
  
    function bindEvents(dualListbox) {
      dualListbox.elements.form.submit(function(e) {
        if (dualListbox.elements.filterInput1.is(':focus')) {
          e.preventDefault();
          dualListbox.elements.filterInput1.focusout();
        } else if (dualListbox.elements.filterInput2.is(':focus')) {
          e.preventDefault();
          dualListbox.elements.filterInput2.focusout();
        }
      });
  
      dualListbox.element.on('bootstrapDualListbox.refresh', function(e, mustClearSelections){
        dualListbox.refresh(mustClearSelections);
      });
  
      dualListbox.elements.filterClear1.on('click', function() {
        dualListbox.setNonSelectedFilter('', true);
      });
  
      dualListbox.elements.filterClear2.on('click', function() {
        dualListbox.setSelectedFilter('', true);
      });
  
      if (dualListbox.settings.eventMoveOverride === false) {
        dualListbox.elements.moveButton.on('click', function() {
          move(dualListbox);
        });
      }
  
      if (dualListbox.settings.eventMoveAllOverride === false) {
        dualListbox.elements.moveAllButton.on('click', function() {
          moveAll(dualListbox);
        });
      }
  
      if (dualListbox.settings.eventRemoveOverride === false) {
        dualListbox.elements.removeButton.on('click', function() {
          remove(dualListbox);
        });
      }
  
      if (dualListbox.settings.eventRemoveAllOverride === false) {
        dualListbox.elements.removeAllButton.on('click', function() {
          removeAll(dualListbox);
        });
      }
  
      dualListbox.elements.filterInput1.on('change keyup', function() {
        filter(dualListbox, 1);
      });
  
      dualListbox.elements.filterInput2.on('change keyup', function() {
        filter(dualListbox, 2);
      });
    }
  
    BootstrapDualListbox.prototype = {
      init: function () {
        // Add the custom HTML template
        this.container = $('' +
          '<div class="bootstrap-duallistbox-container">' +
          ' <div class="box1">' +
          '   <label></label>' +
          '   <span class="info-container">' +
          '     <span class="info"></span>' +
          '     <button type="button" class="btn clear1 pull-right"></button>' +
          '   </span>' +
          '   <input class="filter" type="text">' +
          '   <div class="btn-group buttons">' +
          '     <button type="button" class="btn moveall">' +
          '       <i></i>' +
          '       <i></i>' +
          '     </button>' +
          '     <button type="button" class="btn move">' +
          '       <i></i>' +
          '     </button>' +
          '   </div>' +
          '   <select multiple="multiple"></select>' +
          ' </div>' +
          ' <div class="box2">' +
          '   <label></label>' +
          '   <span class="info-container">' +
          '     <span class="info"></span>' +
          '     <button type="button" class="btn clear2 pull-right"></button>' +
          '   </span>' +
          '   <input class="filter" type="text">' +
          '   <div class="btn-group buttons">' +
          '     <button type="button" class="btn remove">' +
          '       <i></i>' +
          '     </button>' +
          '     <button type="button" class="btn removeall">' +
          '       <i></i>' +
          '       <i></i>' +
          '     </button>' +
          '   </div>' +
          '   <select multiple="multiple"></select>' +
          ' </div>' +
          '</div>')
          .insertBefore(this.element);
  
        // Cache the inner elements
        this.elements = {
          originalSelect: this.element,
          box1: $('.box1', this.container),
          box2: $('.box2', this.container),
          filterInput1: $('.box1 .filter', this.container),
          filterInput2: $('.box2 .filter', this.container),
          filterClear1: $('.box1 .clear1', this.container),
          filterClear2: $('.box2 .clear2', this.container),
          label1: $('.box1 > label', this.container),
          label2: $('.box2 > label', this.container),
          info1: $('.box1 .info', this.container),
          info2: $('.box2 .info', this.container),
          select1: $('.box1 select', this.container),
          select2: $('.box2 select', this.container),
          moveButton: $('.box1 .move', this.container),
          removeButton: $('.box2 .remove', this.container),
          moveAllButton: $('.box1 .moveall', this.container),
          removeAllButton: $('.box2 .removeall', this.container),
          form: $($('.box1 .filter', this.container)[0].form)
        };
  
        // Set select IDs
        this.originalSelectName = this.element.attr('name') || '';
        var select1Id = 'bootstrap-duallistbox-nonselected-list_' + this.originalSelectName,
          select2Id = 'bootstrap-duallistbox-selected-list_' + this.originalSelectName;
        this.elements.select1.attr('id', select1Id);
        this.elements.select2.attr('id', select2Id);
        this.elements.label1.attr('for', select1Id);
        this.elements.label2.attr('for', select2Id);
  
        // Apply all settings
        this.selectedElements = 0;
        this.sortIndex = 0;
        this.elementCount = 0;
        this.setBootstrap2Compatible(this.settings.bootstrap2Compatible);
        this.setFilterTextClear(this.settings.filterTextClear);
        this.setFilterPlaceHolder(this.settings.filterPlaceHolder);
        this.setMoveSelectedLabel(this.settings.moveSelectedLabel);
        this.setMoveAllLabel(this.settings.moveAllLabel);
        this.setRemoveSelectedLabel(this.settings.removeSelectedLabel);
        this.setRemoveAllLabel(this.settings.removeAllLabel);
        this.setMoveOnSelect(this.settings.moveOnSelect);
        this.setPreserveSelectionOnMove(this.settings.preserveSelectionOnMove);
        this.setSelectedListLabel(this.settings.selectedListLabel);
        this.setNonSelectedListLabel(this.settings.nonSelectedListLabel);
        this.setHelperSelectNamePostfix(this.settings.helperSelectNamePostfix);
        this.setSelectOrMinimalHeight(this.settings.selectorMinimalHeight);
  
        updateSelectionStates(this);
  
        this.setShowFilterInputs(this.settings.showFilterInputs);
        this.setNonSelectedFilter(this.settings.nonSelectedFilter);
        this.setSelectedFilter(this.settings.selectedFilter);
        this.setInfoText(this.settings.infoText);
        this.setInfoTextFiltered(this.settings.infoTextFiltered);
        this.setInfoTextEmpty(this.settings.infoTextEmpty);
        this.setFilterOnValues(this.settings.filterOnValues);
        this.setSortByInputOrder(this.settings.sortByInputOrder);
        this.setEventMoveOverride(this.settings.eventMoveOverride);
        this.setEventMoveAllOverride(this.settings.eventMoveAllOverride);
        this.setEventRemoveOverride(this.settings.eventRemoveOverride);
        this.setEventRemoveAllOverride(this.settings.eventRemoveAllOverride);
  
        // Hide the original select
        this.element.hide();
  
        bindEvents(this);
        refreshSelects(this);
  
        return this.element;
      },
      setBootstrap2Compatible: function(value, refresh) {
        this.settings.bootstrap2Compatible = value;
        if (value) {
          this.container.removeClass('row').addClass('row-fluid bs2compatible');
          this.container.find('.box1, .box2').removeClass('col-md-6').addClass('span6');
          this.container.find('.clear1, .clear2').removeClass('btn-purple btn-xs').addClass('btn-mini');
          this.container.find('input, select').removeClass('form-control');
          this.container.find('.btn').removeClass('btn-purple');
          this.container.find('.moveall > i, .move > i').removeClass('fa fa-arrow-right').addClass('icon-arrow-right');
          this.container.find('.removeall > i, .remove > i').removeClass('fa fa-arrow-left').addClass('icon-arrow-left');
        } else {
          this.container.removeClass('row-fluid bs2compatible').addClass('row');
          this.container.find('.box1, .box2').removeClass('span6').addClass('col-md-6');
          this.container.find('.clear1, .clear2').removeClass('btn-mini').addClass('btn-purple btn-xs');
          this.container.find('input, select').addClass('form-control');
          this.container.find('.btn').addClass('btn-purple');
          this.container.find('.moveall > i, .move > i').removeClass('icon-arrow-right').addClass('fa fa-arrow-right');
          this.container.find('.removeall > i, .remove > i').removeClass('icon-arrow-left').addClass('fa fa-arrow-left');
        }
        if (refresh) {
          refreshSelects(this);
        }
        return this.element;
      },
      setFilterTextClear: function(value, refresh) {
        this.settings.filterTextClear = value;
        this.elements.filterClear1.html(value);
        this.elements.filterClear2.html(value);
        if (refresh) {
          refreshSelects(this);
        }
        return this.element;
      },
      setFilterPlaceHolder: function(value, refresh) {
        this.settings.filterPlaceHolder = value;
        this.elements.filterInput1.attr('placeholder', value);
        this.elements.filterInput2.attr('placeholder', value);
        if (refresh) {
          refreshSelects(this);
        }
        return this.element;
      },
      setMoveSelectedLabel: function(value, refresh) {
        this.settings.moveSelectedLabel = value;
        this.elements.moveButton.attr('title', value);
        if (refresh) {
          refreshSelects(this);
        }
        return this.element;
      },
      setMoveAllLabel: function(value, refresh) {
        this.settings.moveAllLabel = value;
        this.elements.moveAllButton.attr('title', value);
        if (refresh) {
          refreshSelects(this);
        }
        return this.element;
      },
      setRemoveSelectedLabel: function(value, refresh) {
        this.settings.removeSelectedLabel = value;
        this.elements.removeButton.attr('title', value);
        if (refresh) {
          refreshSelects(this);
        }
        return this.element;
      },
      setRemoveAllLabel: function(value, refresh) {
        this.settings.removeAllLabel = value;
        this.elements.removeAllButton.attr('title', value);
        if (refresh) {
          refreshSelects(this);
        }
        return this.element;
      },
      setMoveOnSelect: function(value, refresh) {
        if (isBuggyAndroid) {
          value = true;
        }
        this.settings.moveOnSelect = value;
        if (this.settings.moveOnSelect) {
          this.container.addClass('moveonselect');
          var self = this;
          this.elements.select1.on('change', function() {
            move(self);
          });
          this.elements.select2.on('change', function() {
            remove(self);
          });
        } else {
          this.container.removeClass('moveonselect');
          this.elements.select1.off('change');
          this.elements.select2.off('change');
        }
        if (refresh) {
          refreshSelects(this);
        }
        return this.element;
      },
      setPreserveSelectionOnMove: function(value, refresh) {
        // We are forcing to move on select and disabling preserveSelectionOnMove on Android
        if (isBuggyAndroid) {
          value = false;
        }
        this.settings.preserveSelectionOnMove = value;
        if (refresh) {
          refreshSelects(this);
        }
        return this.element;
      },
      setSelectedListLabel: function(value, refresh) {
        this.settings.selectedListLabel = value;
        if (value) {
          this.elements.label2.show().html(value);
        } else {
          this.elements.label2.hide().html(value);
        }
        if (refresh) {
          refreshSelects(this);
        }
        return this.element;
      },
      setNonSelectedListLabel: function(value, refresh) {
        this.settings.nonSelectedListLabel = value;
        if (value) {
          this.elements.label1.show().html(value);
        } else {
          this.elements.label1.hide().html(value);
        }
        if (refresh) {
          refreshSelects(this);
        }
        return this.element;
      },
      setHelperSelectNamePostfix: function(value, refresh) {
        this.settings.helperSelectNamePostfix = value;
        if (value) {
          this.elements.select1.attr('name', this.originalSelectName + value + '1');
          this.elements.select2.attr('name', this.originalSelectName + value + '2');
        } else {
          this.elements.select1.removeAttr('name');
          this.elements.select2.removeAttr('name');
        }
        if (refresh) {
          refreshSelects(this);
        }
        return this.element;
      },
      setSelectOrMinimalHeight: function(value, refresh) {
        this.settings.selectorMinimalHeight = value;
        var height = this.element.height();
        if (this.element.height() < value) {
          height = value;
        }
        this.elements.select1.height(height);
        this.elements.select2.height(height);
        if (refresh) {
          refreshSelects(this);
        }
        return this.element;
      },
      setShowFilterInputs: function(value, refresh) {
        if (!value) {
          this.setNonSelectedFilter('');
          this.setSelectedFilter('');
          refreshSelects(this);
          this.elements.filterInput1.hide();
          this.elements.filterInput2.hide();
        } else {
          this.elements.filterInput1.show();
          this.elements.filterInput2.show();
        }
        this.settings.showFilterInputs = value;
        if (refresh) {
          refreshSelects(this);
        }
        return this.element;
      },
      setNonSelectedFilter: function(value, refresh) {
        if (this.settings.showFilterInputs) {
          this.settings.nonSelectedFilter = value;
          this.elements.filterInput1.val(value);
          if (refresh) {
            refreshSelects(this);
          }
          return this.element;
        }
      },
      setSelectedFilter: function(value, refresh) {
        if (this.settings.showFilterInputs) {
          this.settings.selectedFilter = value;
          this.elements.filterInput2.val(value);
          if (refresh) {
            refreshSelects(this);
          }
          return this.element;
        }
      },
      setInfoText: function(value, refresh) {
        this.settings.infoText = value;
        if (refresh) {
          refreshSelects(this);
        }
        return this.element;
      },
      setInfoTextFiltered: function(value, refresh) {
        this.settings.infoTextFiltered = value;
        if (refresh) {
          refreshSelects(this);
        }
        return this.element;
      },
      setInfoTextEmpty: function(value, refresh) {
        this.settings.infoTextEmpty = value;
        if (refresh) {
          refreshSelects(this);
        }
        return this.element;
      },
      setFilterOnValues: function(value, refresh) {
        this.settings.filterOnValues = value;
        if (refresh) {
          refreshSelects(this);
        }
        return this.element;
      },
      setSortByInputOrder: function(value, refresh){
          this.settings.sortByInputOrder = value;
          if (refresh) {
            refreshSelects(this);
          }
          return this.element;
      },
      setEventMoveOverride: function(value, refresh) {
          this.settings.eventMoveOverride = value;
          if (refresh) {
            refreshSelects(this);
          }
          return this.element;
      },
      setEventMoveAllOverride: function(value, refresh) {
          this.settings.eventMoveAllOverride = value;
          if (refresh) {
            refreshSelects(this);
          }
          return this.element;
      },
      setEventRemoveOverride: function(value, refresh) {
          this.settings.eventRemoveOverride = value;
          if (refresh) {
            refreshSelects(this);
          }
          return this.element;
      },
      setEventRemoveAllOverride: function(value, refresh) {
          this.settings.eventRemoveAllOverride = value;
          if (refresh) {
            refreshSelects(this);
          }
          return this.element;
      },
      getContainer: function() {
        return this.container;
      },
      refresh: function(mustClearSelections) {
        updateSelectionStates(this);
  
        if (!mustClearSelections) {
          saveSelections(this, 1);
          saveSelections(this, 2);
        } else {
          clearSelections(this);
        }
  
        refreshSelects(this);
      },
      destroy: function() {
        this.container.remove();
        this.element.show();
        $.data(this, 'plugin_' + pluginName, null);
        return this.element;
      }
    };
  
    // A really lightweight plugin wrapper around the constructor,
    // preventing against multiple instantiations
    $.fn[ pluginName ] = function (options) {
      var args = arguments;
  
      // Is the first parameter an object (options), or was omitted, instantiate a new instance of the plugin.
      if (options === undefined || typeof options === 'object') {
        return this.each(function () {
          // If this is not a select
          if (!$(this).is('select')) {
            $(this).find('select').each(function(index, item) {
              // For each nested select, instantiate the Dual List Box
              $(item).bootstrapDualListbox(options);
            });
          } else if (!$.data(this, 'plugin_' + pluginName)) {
            // Only allow the plugin to be instantiated once so we check that the element has no plugin instantiation yet
  
            // if it has no instance, create a new one, pass options to our plugin constructor,
            // and store the plugin instance in the elements jQuery data object.
            $.data(this, 'plugin_' + pluginName, new BootstrapDualListbox(this, options));
          }
        });
        // If the first parameter is a string and it doesn't start with an underscore or "contains" the `init`-function,
        // treat this as a call to a public method.
      } else if (typeof options === 'string' && options[0] !== '_' && options !== 'init') {
  
        // Cache the method call to make it possible to return a value
        var returns;
  
        this.each(function () {
          var instance = $.data(this, 'plugin_' + pluginName);
          // Tests that there's already a plugin-instance and checks that the requested public method exists
          if (instance instanceof BootstrapDualListbox && typeof instance[options] === 'function') {
            // Call the method of our plugin instance, and pass it the supplied arguments.
            returns = instance[options].apply(instance, Array.prototype.slice.call(args, 1));
          }
        });
  
        // If the earlier cached method gives a value back return the value,
        // otherwise return this to preserve chainability.
        return returns !== undefined ? returns : this;
      }
  
    };
  
  })(jQuery, window, document);
  