@Override
    public ARGPath getNextPathForInterpolation() {
      ARGPathBuilder errorPathBuilder = ARGPath.builder();

      ARGState current = sources.pop();

      if (!isValidInterpolationRoot(predecessorRelation.get(current))) {
        logger.log(
            Level.FINEST,
            "interpolant of predecessor of ",
            current.getStateId(),
            " is already false, so return empty path");
        return EMPTY_PATH;
      }

      // if the current state is not the root, it is a child of a branch , however, the path should
      // not start with the
      // child, but with the branching node (children are stored on the stack because this needs
      // less book-keeping)
      if (current != root) {
        errorPathBuilder.add(
            predecessorRelation.get(current),
            predecessorRelation.get(current).getEdgeToChild(current));
      }

      while (successorRelation.get(current).iterator().hasNext()) {
        Iterator<ARGState> children = successorRelation.get(current).iterator();
        ARGState child = children.next();
        errorPathBuilder.add(current, current.getEdgeToChild(child));

        // push all other children of the current state, if any, onto the stack for later
        // interpolations
        int size = 1;
        while (children.hasNext()) {
          size++;
          ARGState sibling = children.next();
          logger.log(
              Level.FINEST,
              "\tpush new root ",
              sibling.getStateId(),
              " onto stack for parent ",
              predecessorRelation.get(sibling).getStateId());
          sources.push(sibling);
        }
        assert (size <= 2);

        current = child;
      }

      return errorPathBuilder.build(current);
    }
    @Override
    public ARGPath getNextPathForInterpolation() {
      ARGState current = sources.remove(0);

      assert current.isTarget() : "current element is not a target";

      ARGPathBuilder errorPathBuilder = ARGPath.reverseBuilder();

      errorPathBuilder.add(
          current, FluentIterable.from(AbstractStates.getOutgoingEdges(current)).first().orNull());

      while (predecessorRelation.get(current) != null) {

        ARGState parent = predecessorRelation.get(current);

        if (stateHasFalseInterpolant(parent)) {
          logger.log(
              Level.FINEST,
              "interpolant on path, namely for state ",
              parent.getStateId(),
              " is already false, so return empty path");
          return EMPTY_PATH;
        }

        if (predecessorRelation.get(parent) != null) {
          errorPathBuilder.add(parent, parent.getEdgeToChild(current));
        }

        current = parent;
      }

      return errorPathBuilder.build(current);
    }
  private Collection<Edge> getRelevantChildrenOfState(
      ARGState currentElement, Stack<FunctionBody> functionStack, Set<ARGState> elementsOnPath) {
    // find the next elements to add to the waitlist

    List<ARGState> relevantChildrenOfElement =
        from(currentElement.getChildren()).filter(in(elementsOnPath)).toList();
    relevantChildrenOfElement = chooseIfArbitrary(currentElement, relevantChildrenOfElement);

    // if there is only one child on the path
    if (relevantChildrenOfElement.size() == 1) {
      // get the next ARG state, create a new edge using the same stack and add it to the waitlist
      ARGState elem = Iterables.getOnlyElement(relevantChildrenOfElement);
      CFAEdge e = currentElement.getEdgeToChild(elem);
      Edge newEdge = new Edge(elem, currentElement, e, functionStack);
      return Collections.singleton(newEdge);

    } else if (relevantChildrenOfElement.size() > 1) {
      // if there are more than one relevant child, then this is a condition
      // we need to update the stack
      assert relevantChildrenOfElement.size() == 2;
      Collection<Edge> result = new ArrayList<>(2);
      int ind = 0;
      for (ARGState elem : relevantChildrenOfElement) {
        Stack<FunctionBody> newStack = cloneStack(functionStack);
        CFAEdge e = currentElement.getEdgeToChild(elem);
        FunctionBody currentFunction = newStack.peek();
        assert e instanceof CAssumeEdge;
        CAssumeEdge assumeEdge = (CAssumeEdge) e;
        boolean truthAssumption = assumeEdge.getTruthAssumption();

        String cond = "";

        if (ind == 0) {
          cond = "if ";
        } else if (ind == 1) {
          cond = "else if ";
        } else {
          throw new AssertionError();
        }
        ind++;

        if (truthAssumption) {
          cond += "(" + assumeEdge.getExpression().toASTString() + ")";
        } else {
          cond += "(!(" + assumeEdge.getExpression().toASTString() + "))";
        }

        // create a new block starting with this condition
        currentFunction.enterBlock(currentElement.getStateId(), assumeEdge, cond);

        Edge newEdge = new Edge(elem, currentElement, e, newStack);
        result.add(newEdge);
      }
      return result;
    }
    return Collections.emptyList();
  }
  /**
   * Start the function, puts another body on the function stack.
   *
   * @param firstFunctionElement the first state inside the function
   * @param functionStack the current callstack
   * @param predecessor the previous node
   */
  protected String startFunction(
      ARGState firstFunctionElement, Stack<FunctionBody> functionStack, CFANode predecessor) {
    // create the first stack element using the first element of the function
    CFunctionEntryNode functionStartNode = extractFunctionCallLocation(firstFunctionElement);
    String freshFunctionName = getFreshFunctionName(functionStartNode);

    String lFunctionHeader =
        functionStartNode.getFunctionDefinition().getType().toASTString(freshFunctionName);
    // lFunctionHeader is for example "void foo_99(int a)"

    // create a new function
    FunctionBody newFunction = new FunctionBody(firstFunctionElement.getStateId(), lFunctionHeader);

    // register function
    mFunctionDecls.add(lFunctionHeader + ";");
    mFunctionBodies.add(newFunction);
    functionStack.push(newFunction); // add function to current stack
    return freshFunctionName;
  }
  private Collection<Edge> handleEdge(
      Edge nextEdge,
      Map<Integer, MergeNode> mergeNodes,
      Set<ARGState> elementsOnPath,
      EdgeVisitor callback) {
    ARGState childElement = nextEdge.getChildState();
    CFAEdge edge = nextEdge.getEdge();
    Stack<FunctionBody> functionStack = nextEdge.getStack();

    // clone stack to have a different representation of the function calls and conditions
    // for every element
    functionStack = cloneStack(functionStack);

    // we do not have a single edge, instead a dynamic multi-edge
    if (edge == null) {
      List<CFAEdge> edges = nextEdge.getParentState().getEdgesToChild(childElement);
      for (CFAEdge inner : edges) {
        callback.visit(childElement, inner, functionStack);
      }
    } else {
      callback.visit(childElement, edge, functionStack);
    }

    // how many parents does the child have?
    // ignore parents not on the error path
    int noOfParents = from(childElement.getParents()).filter(in(elementsOnPath)).size();
    assert noOfParents >= 1;

    // handle merging if necessary
    if (noOfParents > 1) {
      assert !((edge instanceof CFunctionCallEdge) || (childElement.isTarget()));

      // this is the end of a condition, determine whether we should continue or backtrack

      int elemId = childElement.getStateId();
      FunctionBody currentFunction = functionStack.peek();
      currentFunction.write("goto label_" + elemId + ";");

      // get the merge node for that node
      MergeNode mergeNode = mergeNodes.get(elemId);
      // if null create new and put in the map
      if (mergeNode == null) {
        mergeNode = new MergeNode(elemId);
        mergeNodes.put(elemId, mergeNode);
      }

      // this tells us the number of edges (entering that node) processed so far
      int noOfProcessedBranches = mergeNode.addBranch(currentFunction);

      // if all edges are processed
      if (noOfParents == noOfProcessedBranches) {
        // all branches are processed, now decide which nodes to remove from the stack
        List<FunctionBody> incomingStacks = mergeNode.getIncomingStates();

        FunctionBody newFunction = processIncomingStacks(incomingStacks);

        // replace the current function body with the right one
        functionStack.pop();
        functionStack.push(newFunction);

        newFunction.write("label_" + elemId + ": ;");

      } else {
        return Collections.emptySet();
      }
    }

    return getRelevantChildrenOfState(childElement, functionStack, elementsOnPath);
  }