       value:      $option[0].value
       selected:   false
       disabled:   false
-      match_type: if append then null else 0
+      match_type: if append then null else -1
 
     if append
       @all_options.push chosen_option


  exact_matches: ->
    $.grep @available_options, (option) ->
      option.match_type is 0

  includes_blank: ->
    not not @blank_option()


    return null

  reset_filter: ->
    option.score = option.index * -1 for option in @all_options
    return @

  apply_filter: (value) ->
    @reset_filter()

    if (value = $.trim(value))
      num_options = @all_options.length
      exact_query = value.toLowerCase()
      query       = $.grep(exact_query.replace(Parser.escape_exp, "\\$&").split(/\W/), (s) -> s.length)

      expressions_collection = $.map(query, (w, i) ->
        return [[new RegExp("^#{w}$", "i"), new RegExp("^#{w}", "i"), new RegExp(w, "i")]]
      )

      for option in @all_options
        option.score = 0

        if option.label.toLowerCase() is exact_query
          option.match_type = -1
        else
          option.match_type = null

        words = $.grep(option.label.split(/\W/), (s) -> s.length)

        for word, word_index in words
          for expressions in expressions_collection
            for expression, expression_index in expressions
              if word.match(expression)
                unless option.match_type is -1
                  option.match_type = expression_index

                option.score += num_options * (expressions.length - option.match_type) / (word_index + 1)
                break
              else if expression_index is expressions.length - 1
                option.score -= num_options * expressions.length / words.length

    @order()
    return @

  # Re-order all_options array keeping the optgroup order
  order: ->
    groups = {}

    for option in @all_options
      group_id = if option.$group then option.$group.group_id else -1
      groups[group_id] ||= []
      groups[group_id].push(option)

    @all_options       = []
    @available_options = []

    for own group_id, value of groups
      @all_options = @all_options.concat(@order_group(value))

    for option in @all_options
      if not option.blank
        @available_options.push(option)

    return @

  order_group: (group) ->
    group
      .sort (a, b) -> a.index - b.index
      .sort (a, b) -> b.score - a.score

  default_parser: (attrs) ->
    value: attrs.value
