Program: 55173
Project: 55173
Buggy source:
/** 
 * This method implements the post-visit during the depth-first traversal. When the post visit happens, all of the descendants have been processed, so this method connects all of the current node's predecessors to the current node.
 * @param node The node currently processed during the post-visit.
 * @see eu.stratosphere.pact.common.util.Visitor#postVisit(eu.stratosphere.pact.common.plan.Visitable)
 */
@Override public void postVisit(PlanNode node){
  try {
    if (node instanceof SourcePlanNode || node instanceof UnionPlanNode) {
      return;
    }
    if (node instanceof IterationPlanNode) {
      if (this.currentIteration != null) {
        throw new CompilerException("String_Node_Str");
      }
      this.currentIteration=(IterationPlanNode)node;
      this.currentIteration.acceptForStepFunction(this);
      this.currentIteration=null;
      if (node instanceof WorksetIterationPlanNode) {
        WorksetIterationPlanNode wsNode=(WorksetIterationPlanNode)node;
        AbstractJobVertex headVertex=this.iterations.get(wsNode).getHeadTask();
        TaskConfig headConfig=new TaskConfig(headVertex.getConfiguration());
        int inputIndex=headConfig.getDriverStrategy().getNumInputs();
        headConfig.setIterationHeadSolutionSetInputIndex(inputIndex);
        translateChannel(wsNode.getInitialSolutionSetInput(),inputIndex,headVertex,headConfig);
      }
      return;
    }
 else     if (node instanceof SolutionSetPlanNode) {
      if (node.getOutgoingChannels().size() != 1) {
        throw new CompilerException("String_Node_Str");
      }
      Channel c=node.getOutgoingChannels().get(0);
      DualInputPlanNode target=(DualInputPlanNode)c.getTarget();
      AbstractJobVertex accessingVertex=this.vertices.get(target);
      TaskConfig conf=new TaskConfig(accessingVertex.getConfiguration());
      int inputNum=c == target.getInput1() ? 0 : c == target.getInput2() ? 1 : -1;
      if (inputNum == -1) {
        throw new CompilerException();
      }
      if (conf.getDriver().equals(MatchDriver.class)) {
        conf.setDriver(inputNum == 0 ? SolutionSetFirstJoinDriver.class : SolutionSetSecondJoinDriver.class);
      }
 else       if (conf.getDriver().equals(CoGroupDriver.class)) {
        conf.setDriver(inputNum == 0 ? SolutionSetFirstCoGroupDriver.class : SolutionSetSecondCoGroupDriver.class);
      }
 else {
        throw new CompilerException("String_Node_Str");
      }
      conf.setSolutionSetSerializer(((SolutionSetPlanNode)node).getContainingIterationNode().getSolutionSetSerializer());
      IterationDescriptor iter=this.iterations.get(((SolutionSetPlanNode)node).getContainingIterationNode());
      TaskConfig headConf=iter.getHeadConfig();
      TypeSerializerFactory<?> otherSerializer;
      TypeComparatorFactory<?> otherComparator;
      if (inputNum == 0) {
        otherSerializer=target.getInput2().getSerializer();
        otherComparator=target.getComparator2();
      }
 else {
        otherSerializer=target.getInput1().getSerializer();
        otherComparator=target.getComparator1();
      }
      headConf.setSolutionSetProberSerializer(otherSerializer);
      headConf.setSolutionSetProberComparator(otherComparator);
      headConf.setSolutionSetPairComparator(target.getPairComparator());
      return;
    }
    final AbstractJobVertex targetVertex=this.vertices.get(node);
    if (targetVertex == null) {
      final TaskInChain chainedTask;
      if ((chainedTask=this.chainedTasks.get(node)) != null) {
        final Iterator<Channel> inConns=node.getInputs();
        if (!inConns.hasNext()) {
          throw new CompilerException("String_Node_Str");
        }
        final Channel inConn=inConns.next();
        if (inConns.hasNext()) {
          throw new CompilerException("String_Node_Str");
        }
        if (inConn.getLocalStrategy() != null && inConn.getLocalStrategy() != LocalStrategy.NONE) {
          throw new CompilerException("String_Node_Str");
        }
        if (inConn.getShipStrategy() != null && inConn.getShipStrategy() != ShipStrategyType.FORWARD) {
          throw new CompilerException("String_Node_Str");
        }
        AbstractJobVertex container=chainedTask.getContainingVertex();
        if (container == null) {
          final PlanNode sourceNode=inConn.getSource();
          container=this.vertices.get(sourceNode);
          if (container == null) {
            container=this.chainedTasks.get(sourceNode).getContainingVertex();
            if (container == null)             throw new IllegalStateException("String_Node_Str");
          }
 else {
            new TaskConfig(container.getConfiguration()).addOutputShipStrategy(ShipStrategyType.FORWARD);
          }
          chainedTask.setContainingVertex(container);
        }
        chainedTask.getTaskConfig().setInputSerializer(inConn.getSerializer(),0);
        this.chainedTasksInSequence.add(chainedTask);
        return;
      }
 else       if (node instanceof BulkPartialSolutionPlanNode || node instanceof WorksetPlanNode) {
        return;
      }
 else {
        throw new CompilerException("String_Node_Str");
      }
    }
    final TaskConfig targetVertexConfig=new TaskConfig(targetVertex.getConfiguration());
    final Iterator<Channel> inConns;
    if (node instanceof BulkPartialSolutionPlanNode) {
      inConns=((BulkPartialSolutionPlanNode)node).getContainingIterationNode().getInputs();
      targetVertexConfig.setIterationHeadPartialSolutionOrWorksetInputIndex(0);
    }
 else     if (node instanceof WorksetPlanNode) {
      WorksetPlanNode wspn=(WorksetPlanNode)node;
      inConns=Collections.singleton(wspn.getContainingIterationNode().getInput2()).iterator();
      targetVertexConfig.setIterationHeadPartialSolutionOrWorksetInputIndex(0);
      targetVertexConfig.setIterationHeadSolutionSetInputIndex(1);
    }
 else {
      inConns=node.getInputs();
    }
    if (!inConns.hasNext()) {
      throw new CompilerException("String_Node_Str");
    }
    for (int inputIndex=0; inConns.hasNext(); inputIndex++) {
      Channel input=inConns.next();
      translateChannel(input,inputIndex,targetVertex,targetVertexConfig);
    }
  }
 catch (  Exception e) {
    throw new CompilerException("String_Node_Str" + e.getMessage(),e);
  }
}

Fixed version (ground truth):
/** 
 * This method implements the post-visit during the depth-first traversal. When the post visit happens, all of the descendants have been processed, so this method connects all of the current node's predecessors to the current node.
 * @param node The node currently processed during the post-visit.
 * @see eu.stratosphere.pact.common.util.Visitor#postVisit(eu.stratosphere.pact.common.plan.Visitable)
 */
@Override public void postVisit(PlanNode node){
  try {
    if (node instanceof SourcePlanNode || node instanceof UnionPlanNode) {
      return;
    }
    if (node instanceof IterationPlanNode) {
      if (this.currentIteration != null) {
        throw new CompilerException("String_Node_Str");
      }
      this.currentIteration=(IterationPlanNode)node;
      this.currentIteration.acceptForStepFunction(this);
      this.currentIteration=null;
      if (node instanceof WorksetIterationPlanNode) {
        WorksetIterationPlanNode wsNode=(WorksetIterationPlanNode)node;
        AbstractJobVertex headVertex=this.iterations.get(wsNode).getHeadTask();
        TaskConfig headConfig=new TaskConfig(headVertex.getConfiguration());
        int inputIndex=headConfig.getDriverStrategy().getNumInputs();
        headConfig.setIterationHeadSolutionSetInputIndex(inputIndex);
        translateChannel(wsNode.getInitialSolutionSetInput(),inputIndex,headVertex,headConfig);
      }
      return;
    }
 else     if (node instanceof SolutionSetPlanNode) {
      if (node.getOutgoingChannels().size() != 1) {
        throw new CompilerException("String_Node_Str");
      }
      Channel c=node.getOutgoingChannels().get(0);
      DualInputPlanNode target=(DualInputPlanNode)c.getTarget();
      AbstractJobVertex accessingVertex=this.vertices.get(target);
      TaskConfig conf=new TaskConfig(accessingVertex.getConfiguration());
      int inputNum=c == target.getInput1() ? 0 : c == target.getInput2() ? 1 : -1;
      if (inputNum == -1) {
        throw new CompilerException();
      }
      if (conf.getDriver().equals(MatchDriver.class)) {
        conf.setDriver(inputNum == 0 ? SolutionSetFirstJoinDriver.class : SolutionSetSecondJoinDriver.class);
      }
 else       if (conf.getDriver().equals(CoGroupDriver.class)) {
        conf.setDriver(inputNum == 0 ? SolutionSetFirstCoGroupDriver.class : SolutionSetSecondCoGroupDriver.class);
      }
 else {
        throw new CompilerException("String_Node_Str");
      }
      conf.setSolutionSetSerializer(((SolutionSetPlanNode)node).getContainingIterationNode().getSolutionSetSerializer());
      IterationDescriptor iter=this.iterations.get(((SolutionSetPlanNode)node).getContainingIterationNode());
      TaskConfig headConf=iter.getHeadConfig();
      TypeSerializerFactory<?> otherSerializer;
      TypeComparatorFactory<?> otherComparator;
      if (inputNum == 0) {
        otherSerializer=target.getInput2().getSerializer();
        otherComparator=target.getComparator2();
      }
 else {
        otherSerializer=target.getInput1().getSerializer();
        otherComparator=target.getComparator1();
      }
      headConf.setSolutionSetProberSerializer(otherSerializer);
      headConf.setSolutionSetProberComparator(otherComparator);
      headConf.setSolutionSetPairComparator(target.getPairComparator());
      return;
    }
    final AbstractJobVertex targetVertex=this.vertices.get(node);
    if (targetVertex == null) {
      final TaskInChain chainedTask;
      if ((chainedTask=this.chainedTasks.get(node)) != null) {
        final Iterator<Channel> inConns=node.getInputs();
        if (!inConns.hasNext()) {
          throw new CompilerException("String_Node_Str");
        }
        final Channel inConn=inConns.next();
        if (inConns.hasNext()) {
          throw new CompilerException("String_Node_Str");
        }
        if (inConn.getLocalStrategy() != null && inConn.getLocalStrategy() != LocalStrategy.NONE) {
          throw new CompilerException("String_Node_Str");
        }
        if (inConn.getShipStrategy() != null && inConn.getShipStrategy() != ShipStrategyType.FORWARD) {
          throw new CompilerException("String_Node_Str");
        }
        AbstractJobVertex container=chainedTask.getContainingVertex();
        if (container == null) {
          final PlanNode sourceNode=inConn.getSource();
          container=this.vertices.get(sourceNode);
          if (container == null) {
            container=this.chainedTasks.get(sourceNode).getContainingVertex();
            if (container == null)             throw new IllegalStateException("String_Node_Str");
          }
 else {
            new TaskConfig(container.getConfiguration()).addOutputShipStrategy(ShipStrategyType.FORWARD);
          }
          chainedTask.setContainingVertex(container);
        }
        chainedTask.getTaskConfig().setInputSerializer(inConn.getSerializer(),0);
        this.chainedTasksInSequence.add(chainedTask);
        return;
      }
 else       if (node instanceof BulkPartialSolutionPlanNode || node instanceof WorksetPlanNode) {
        return;
      }
 else {
        throw new CompilerException("String_Node_Str");
      }
    }
    final TaskConfig targetVertexConfig=new TaskConfig(targetVertex.getConfiguration());
    final Iterator<Channel> inConns;
    if (node instanceof BulkPartialSolutionPlanNode) {
      inConns=((BulkPartialSolutionPlanNode)node).getContainingIterationNode().getInputs();
      targetVertexConfig.setIterationHeadPartialSolutionOrWorksetInputIndex(0);
    }
 else     if (node instanceof WorksetPlanNode) {
      WorksetPlanNode wspn=(WorksetPlanNode)node;
      inConns=Collections.singleton(wspn.getContainingIterationNode().getInput2()).iterator();
      targetVertexConfig.setIterationHeadPartialSolutionOrWorksetInputIndex(0);
      targetVertexConfig.setIterationHeadSolutionSetInputIndex(1);
    }
 else {
      inConns=node.getInputs();
    }
    if (!inConns.hasNext()) {
      throw new CompilerException("String_Node_Str");
    }
    int inputIndex=0;
    while (inConns.hasNext()) {
      Channel input=inConns.next();
      inputIndex+=translateChannel(input,inputIndex,targetVertex,targetVertexConfig);
    }
  }
 catch (  Exception e) {
    throw new CompilerException("String_Node_Str" + e.getMessage(),e);
  }
}