/*
 * Copyright 2000-2017 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.debugger.streams.trace.impl.handler;

import com.intellij.debugger.streams.trace.impl.handler.type.GenericType;
import com.intellij.debugger.streams.wrapper.IntermediateStreamCall;
import com.intellij.debugger.streams.wrapper.TerminatorStreamCall;
import com.intellij.debugger.streams.wrapper.impl.IntermediateStreamCallImpl;
import com.intellij.openapi.util.TextRange;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author Vitaliy.Bibaev
 */
public class MatchHandler extends CallTraceHandlerBase {
  private final PeekTracerHandler myBeforeFilterPeekInserter;
  private final PeekTracerHandler myAfterFilterPeekInserter;
  private final GenericType myTypeBefore;

  MatchHandler(@NotNull TerminatorStreamCall call) {
    final GenericType typeBefore = call.getTypeBefore();
    myBeforeFilterPeekInserter = new PeekTracerHandler(0, "match", typeBefore, typeBefore);
    myAfterFilterPeekInserter = new PeekTracerHandler(1, "match", typeBefore, typeBefore);
    myTypeBefore = typeBefore;
  }

  @NotNull
  @Override
  protected List<Variable> getVariables() {
    final List<Variable> variables = new ArrayList<>(myBeforeFilterPeekInserter.getVariables());
    variables.addAll(myAfterFilterPeekInserter.getVariables());
    return variables;
  }

  @NotNull
  @Override
  public String prepareResult() {
    return myBeforeFilterPeekInserter.prepareResult() + myAfterFilterPeekInserter.prepareResult();
  }

  @NotNull
  @Override
  public String getResultExpression() {
    return "new Object[] { " +
           myBeforeFilterPeekInserter.getResultExpression() +
           ", " +
           myAfterFilterPeekInserter.getResultExpression() +
           "}";
  }

  @NotNull
  @Override
  public List<IntermediateStreamCall> additionalCallsBefore() {
    final ArrayList<IntermediateStreamCall> calls = new ArrayList<>(myBeforeFilterPeekInserter.additionalCallsBefore());
    calls.add(new IntermediateStreamCallImpl("filter", "", myTypeBefore, myTypeBefore, TextRange.EMPTY_RANGE));
    calls.addAll(myAfterFilterPeekInserter.additionalCallsBefore());

    return calls;
  }

  @NotNull
  @Override
  public List<IntermediateStreamCall> additionalCallsAfter() {
    return Collections.emptyList();
  }
}

@@ -727,16 +727,75 @@
 icType;%0A
+import com.intellij.debugger.streams.wrapper.CallArgument;%0A
 import c
@@ -914,32 +914,100 @@
 atorStreamCall;%0A
+import com.intellij.debugger.streams.wrapper.impl.CallArgumentImpl;%0A
 import com.intel
@@ -1328,16 +1328,87 @@
 rBase %7B%0A
+  private static final String PREDICATE_VARIABLE_NAME = %22predicate42%22;%0A
   privat
@@ -1563,16 +1563,61 @@
 eBefore;
+%0A  private final TerminatorStreamCall myCall;
 %0A%0A  Matc
@@ -1934,16 +1934,35 @@
 Before;%0A
+    myCall = call;%0A
   %7D%0A%0A  @
@@ -2182,24 +2182,194 @@
 riables());%0A
+    final CallArgument predicate = myCall.getArguments().get(0);%0A    variables.add(new VariableImpl(predicate.getType(), PREDICATE_VARIABLE_NAME, predicate.getText()));%0A%0A
     return v
@@ -3012,80 +3012,340 @@
 ));%0A
-    calls.add(new IntermediateStreamCallImpl(%22filter%22, %22%22, myTypeBefore,
+%0A    final CallArgument predicate = myCall.getArguments().get(0);%0A    final CallArgumentImpl argument = new CallArgumentImpl(predicate.getType(), predicate.getText() + %22.negate()%22);%0A    calls.add(new IntermediateStreamCallImpl(%22filter%22, Collections.singletonList(argument), myTypeBefore,%0A                                            
  myT

Use type information in the handler