def insert_before(index, *filter_spec, &block)
      filter = build_filter(filter_spec, &block)

      synchronize do
        id = index_at(index)
        unless id && (0...@filters.size).cover?(id)
          raise ArgumentError, "No such filter to insert before: #{index.inspect}"
        end

        @filters.insert(id, filter)
      end
      self
    end
def insert_before(index, *filter_spec, &block)
      filter = build_filter(filter_spec, &block)

      synchronize do
        id = index_at(index)
        unless id && (0...@filters.size).cover?(id)
          raise ArgumentError, "No such filter to insert before: #{index.inspect}"
        end

        @filters.insert(id, filter)
      end
      self
    end
Insert a new filter before an existing filter in the filter chain.

 @param index [Integer, Class, String, Object] The existing filter before
   which the new one should be inserted. It can be described in different
   ways: When given an `Integer`, we expect it to be the index number; when
   given a `Class`, we try to find the first filter being of that type;
   when given a `String`, we try to find the first filter being of a type
   named like that; when given any other object, we assume it is a filter
   and search for that.
 @param filter_spec (see #build_filter)
 @raise [ArgumentError] if no existing filter could be found at `index`
 @raise [TypeError] if we could not build a filter from the given
   `filter_spec`
 @return [self]