/*
 * Copyright 2000-2011 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.intellij.openapi.vcs.checkin;

import com.intellij.openapi.util.TextRange;
import com.intellij.util.PairConsumer;
import com.intellij.util.containers.Convertor;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @author irengrig
 *         Date: 2/18/11
 *         Time: 12:04 AM
 *
 *         keeps state (position in areas) between invocations
 */
public class StepIntersection<Data, Area> {
  private final Convertor<Data,TextRange> myDataConvertor;
  private final Convertor<Area,TextRange> myAreasConvertor;
  private TextRange myDataRange;
  private TextRange myAreaRange;
  private Data myCurData;
  private Iterator<Data> myDataIterator;
  private int myAreaIndex;
  private Area myCurArea;
  private final List<Area> myAreas;
  private final HackSearch<Data,Area,TextRange> myHackSearch;

  public StepIntersection(Convertor<Data, TextRange> dataConvertor,
                          Convertor<Area, TextRange> areasConvertor,
                          final List<Area> areas) {
    myAreas = areas;
    myAreaIndex = 0;
    myDataConvertor = dataConvertor;
    myAreasConvertor = areasConvertor;
    myHackSearch = new HackSearch<>(myDataConvertor, myAreasConvertor,
                                    (o1, o2) -> o1.intersects(o2) ? 0 : o1.getStartOffset() < o2.getStartOffset() ? -1 : 1);
  }

  public void resetIndex() {
    myAreaIndex = 0;
  }

  public List<Data> process(final Iterable<Data> data) {
    final List<Data> result = new ArrayList<>();
    process(data, (data1, area) -> result.add(data1));
    return result;
  }

  public void process(final Iterable<Data> data, final PairConsumer<Data, Area> consumer) {
    myDataIterator = data.iterator();

    if (! myDataIterator.hasNext() || noMoreAreas()) return;
    dataStep();
    initArea();
    while (! noMoreAreas()) {
      final boolean intersects = myAreaRange.intersects(myDataRange);
      if (intersects) {
        consumer.consume(myCurData, myCurArea);
      }
      // take next
      if (! myDataIterator.hasNext() && noMoreAreas()) break;
      if (! myDataIterator.hasNext()) {
        areaStep();
        continue;
      }
      if (noMoreAreas()) {
        dataStep();
        continue;
      }
      if (myDataRange.getEndOffset() < myAreaRange.getEndOffset()) {
        dataStep();
      } else {
        areaStep();
      }
    }
  }

  private boolean noMoreAreas() {
    return (myAreaIndex >= myAreas.size());
  }

  private void initArea() {
    myAreaIndex = 0;
    myCurArea = myAreas.get(myAreaIndex);
    myAreaRange = myAreasConvertor.convert(myCurArea);
  }

  private void areaStep() {
    // a hack here
    final int idx = myHackSearch.search(myAreas.subList(myAreaIndex + 1, myAreas.size()), myCurData);
    myAreaIndex = myAreaIndex + 1 + idx;
    if (myAreaIndex >= myAreas.size()) {
      return;
    }
    /*assert myAreaRange == null || myAreaRange.getEndOffset() < myAreasConvertor.convert(myAreas.get(myAreaIndex)).getStartOffset() :
      "Area ranges intersect: first: " + myAreaRange + ", second: " + myAreasConvertor.convert(myAreas.get(myAreaIndex)) + ", text: '" +
      myDebugDocumentTextGetter.get() + "'";*/
    myCurArea = myAreas.get(myAreaIndex);
    myAreaRange = myAreasConvertor.convert(myCurArea);
  }

  private void dataStep() {
    myCurData = myDataIterator.next();
    /*assert myDataRange == null || myDataRange.getEndOffset() < myDataConvertor.convert(myCurData).getStartOffset() :
      "Data ranges intersect: first: " + myDataRange + ", second: " + myDataConvertor.convert(myCurData) + ", text: '" +
      myDebugDocumentTextGetter.get() + "'";*/
    myDataRange = myDataConvertor.convert(myCurData);
  }
}

@@ -1952,63 +1952,8 @@
  %7D%0A%0A
-  public void resetIndex() %7B%0A    myAreaIndex = 0;%0A  %7D%0A%0A
   pu

remove unused method