/*
 * Copyright 2000-2013 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.lang;

import com.intellij.openapi.util.Condition;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import org.jetbrains.annotations.NotNull;

import java.util.List;

public class WhitespacesBinders {
  public static final WhitespacesAndCommentsBinder DEFAULT_RIGHT_BINDER = new WhitespacesAndCommentsBinder() {
    public int getEdgePosition(List<IElementType> tokens, boolean atStreamEdge, TokenTextGetter getter) {
      return 0;
    }
  };
  public static final WhitespacesAndCommentsBinder DEFAULT_LEFT_BINDER = new WhitespacesAndCommentsBinder() {
    public int getEdgePosition(List<IElementType> tokens, boolean atStreamEdge, TokenTextGetter getter) {
      return tokens.size();
    }
  };

  public static final WhitespacesAndCommentsBinder GREEDY_LEFT_BINDER = DEFAULT_RIGHT_BINDER;
  public static final WhitespacesAndCommentsBinder GREEDY_RIGHT_BINDER = DEFAULT_LEFT_BINDER;

  public static WhitespacesAndCommentsBinder leadingCommentsBinder(@NotNull Condition<IElementType> isCommentCondition) {
    return new LeadingCommentsBinder(isCommentCondition);
  }

  public static WhitespacesAndCommentsBinder leadingCommentsBinder(IElementType... commentTypes) {
    return leadingCommentsBinder(TokenSet.create(commentTypes));
  }

  public static WhitespacesAndCommentsBinder leadingCommentsBinder(@NotNull final TokenSet commentTypes) {
    return leadingCommentsBinder(new Condition<IElementType>() {
      @Override
      public boolean value(IElementType type) {
        return commentTypes.contains(type);
      }
    });
  }

  private static class LeadingCommentsBinder implements WhitespacesAndCommentsBinder {
    @NotNull private final Condition<IElementType> myIsCommentCondition;

    LeadingCommentsBinder(@NotNull Condition<IElementType> isCommentCondition) {
      myIsCommentCondition = isCommentCondition;
    }

    @Override
    public int getEdgePosition(List<IElementType> tokens, boolean atStreamEdge, TokenTextGetter getter) {
      int i = 0;
      while (i < tokens.size() && !myIsCommentCondition.value(tokens.get(i))) {
        i++;
      }
      return i;
    }
  }

  private WhitespacesBinders() {
  }
}

@@ -626,52 +626,8 @@
 g;%0A%0A
-import com.intellij.openapi.util.Condition;%0A
 impo
@@ -805,16 +805,54 @@
 nders %7B%0A
+  private WhitespacesBinders() %7B%0A  %7D%0A%0A
   public
@@ -1612,50 +1612,35 @@
 ull 
-Condition%3CIElementType%3E isCommentCondition
+final TokenSet commentTypes
 ) %7B%0A
@@ -1654,23 +1654,30 @@
 urn new 
-Leading
+WhitespacesAnd
 Comments
@@ -1687,371 +1687,228 @@
 der(
-isCommentCondition);%0A  %7D%0A%0A  public static WhitespacesAndCommentsBinder leadingCommentsBinder(IElementType... commentTypes) %7B%0A    return leadingCommentsBinder(TokenSet.create(commentTypes));%0A  %7D%0A%0A  public static WhitespacesAndCommentsBinder leadingCommentsBinder(@NotNull final TokenSet commentTypes) %7B%0A    return leadingCommentsBinder(new Condition%3CIElementType%3E(
+) %7B%0A      @Override%0A      public int getEdgePosition(List%3CIElementType%3E tokens, boolean atStreamEdge, TokenTextGetter getter) %7B%0A        int i = 0;%0A        while (i %3C tokens.size() && !commentTypes.contains(tokens.get(i))
 ) %7B%0A
@@ -1917,108 +1917,43 @@
     
+ 
-@Override%0A      public boolean value(IElementType type) %7B%0A        return commentTypes.contains(type)
+   i++;%0A        %7D%0A        return i
 ;%0A  
@@ -1963,17 +1963,16 @@
  %7D%0A    %7D
-)
 ;%0A  %7D%0A%0A 
@@ -1977,22 +1977,21 @@
 %0A  p
-rivate
+ublic
  static 
 clas
@@ -1990,289 +1990,150 @@
 tic 
-class LeadingCommentsBinder implements WhitespacesAndCommentsBinder %7B%0A    @NotNull private final Condition%3CIElementType%3E myIsCommentCondition;%0A%0A    LeadingCommentsBinder(@NotNull Condition%3CIElementType%3E isCommentCondition) %7B%0A      myIsCommentCondition = isCommentCondition;%0A    %7D%0A%0A
+WhitespacesAndCommentsBinder trailingCommentsBinder(@NotNull final TokenSet commentTypes) %7B%0A    return new WhitespacesAndCommentsBinder() %7B%0A  
     
@@ -2138,24 +2138,26 @@
   @Override%0A
+  
     public i
@@ -2252,32 +2252,34 @@
 er) %7B%0A      
+  
 int i = 
 0;%0A      whi
@@ -2266,25 +2266,41 @@
 int i = 
-0
+tokens.size() - 1
 ;%0A      
 while (i
@@ -2287,24 +2287,26 @@
  - 1;%0A      
+ 
+ 
 while (i %3C t
@@ -2306,54 +2306,38 @@
  (i 
-%3C tokens.size() && !myIsCommentCondition.value
+%3E= 0 && !commentTypes.contains
 (tok
@@ -2355,29 +2355,33 @@
 ) %7B%0A        
-i++;%0A
+  i--;%0A  
       %7D%0A    
@@ -2378,32 +2378,34 @@
     %7D%0A      
+ 
+ 
 return i
 ;%0A    %7D%0A  %7D%0A
@@ -2396,56 +2396,32 @@
 rn i
+ + 1
 ;%0A    
-%7D%0A
   %7D%0A
-%0A
   
-private WhitespacesBinders() %7B
+  %7D;
 %0A  %7D%0A
+%0A
 %7D%0A

introduce trailingCommentsBinder & simplify