anchor.diff:           chain_op/4
           ]).
   -include("riak_search.hrl").
  +-ifdef(TEST).
  +-include_lib("eunit/include/eunit.hrl").
  +-endif.
   -define(INDEX_DOCID(Term), ({element(1, Term), element(2, Term)})).
   
   %%% Conduct a proximity match over the terms. The #proximity operator
  
positive.code: %% Return true if all of the terms exist within Proximity words from
  %% eachother.
  is_exact_match(Positions) ->
      is_exact_match_1(undefined, Positions).
  is_exact_match_1(LastMin, Positions) ->
      case remove_smallest_position(LastMin, Positions) of
          undefined -> 
              false;
          {Min, Max, NextPass} ->
              case is_exact_match_2(lists:seq(Min, Max), [hd(X) || X <- NextPass]) of
                  true -> 
                      true;
                  false ->
                      is_exact_match_1(Min, NextPass)
              end
      end.
  %% Return true if the two lists match. Broken out because we'll
  %% eventually need to handle skipped terms in here.
  %% TODO - Handle skipped terms.
  is_exact_match_2(L1, L2) ->
      L1 == L2.
  
  
  %% Given a result iterator, only return results that are within a
  %% certain proximity of eachother.
  
negative.code:     %% Hit an eof, no more results...
      {eof, []}.
  
  
  -ifdef(TEST).
  
  remove_next_term_position_1_test() ->
      %% Test when ToRemove == undefined...
      Input =
          [[1,2,3],
           [4,5,6],
           [7,8,9]],
      Expected =
          [[2,3],
           [4,5,6],
           [7,8,9]],
      ?assertEqual(remove_next_term_position(Input), Expected).
  
  remove_next_term_position_2_test() ->
      %% Test when there is a single matching position in middle list...
      Input =
          [[4,5,6],
           [1,2,3],
           [7,8,9]],
      Expected =
          [[4,5,6],
           [2,3],
           [7,8,9]],
      ?assertEqual(remove_next_term_position(Input), Expected).
  
  remove_next_term_position_3_test() ->
      %% Test when there is a single matching position in end list...
      Input =
          [[4,5,6],
           [7,8,9],
           [1,2,3]],
      Expected =
          [[4,5,6],
           [7,8,9],
           [2,3]],
      ?assertEqual(remove_next_term_position(Input), Expected).
  
  remove_next_term_position_4_test() ->
      %% Test when there are multiple matching positions. Should only remove the last one.
      Input =
          [[1,2,3],
           [4,5,6],
           [7,8,9],
           [1,2,3]],
      Expected =
          [[1,2,3],
           [4,5,6],
           [7,8,9],
           [2,3]],
      ?assertEqual(remove_next_term_position(Input), Expected).
  
  remove_next_term_position_5_test() ->
      %% Test when there are multiple matching positions. Should only remove the last one.
      Input =
          [[0],
           [1,2,3],
           [4,5,6],
           [7,8,9],
           [1,2,3]],
      Expected =
          [[0],
           [1,2,3],
           [4,5,6],
           [7,8,9],
           [2,3]],
      ?assertEqual(remove_next_term_position(Input), Expected).
  
  remove_next_term_position_6_test() ->
      %% Test when a list is empty...
      Input =
          [[1,2,3],
           [4,5,6],
           [],
           [1,2,3]],
      Expected =
          undefined,
      ?assertEqual(remove_next_term_position(Input), Expected).
  
  -endif.
  