private static void condenseSequencesRec(Statement stat) {

    if (stat.type == StatementType.SEQUENCE) {

      List<Statement> lst = new ArrayList<>(stat.getStats());

      boolean unfolded = false;

      // unfold blocks
      for (int i = 0; i < lst.size(); i++) {
        Statement st = lst.get(i);
        if (st.type == StatementType.SEQUENCE) {

          removeEmptyStatements((SequenceStatement)st);

          if (i == lst.size() - 1 || isSequenceDisbandable(st, lst.get(i + 1))) {
            // move predecessors
            Statement first = st.getFirst();
            for (StatEdge edge : st.getAllPredecessorEdges()) {
              st.removePredecessor(edge);
              edge.getSource().changeEdgeNode(EdgeDirection.FORWARD, edge, first);
              first.addPredecessor(edge);
            }

            // move successors
            Statement last = st.getStats().getLast();
            if (last.getAllSuccessorEdges().isEmpty() && i < lst.size() - 1) {
              last.addSuccessor(new StatEdge(EdgeType.REGULAR, last, lst.get(i + 1)));
            }
            else {
              for (StatEdge edge : last.getAllSuccessorEdges()) {
                if (i == lst.size() - 1) {
                  if (edge.closure == st) {
                    stat.addLabeledEdge(edge);
                  }
                }
                else {
                  edge.getSource().changeEdgeType(EdgeDirection.FORWARD, edge, EdgeType.REGULAR);
                  edge.closure.getLabelEdges().remove(edge);
                  edge.closure = null;
                }
              }
            }

            for (StatEdge edge : st.getAllSuccessorEdges()) {
              st.removeSuccessor(edge);
            }

            for (StatEdge edge : new HashSet<>(st.getLabelEdges())) {
              if (edge.getSource() != last) {
                last.addLabeledEdge(edge);
              }
            }

            lst.remove(i);
            lst.addAll(i, st.getStats());
            i--;

            unfolded = true;
          }
        }
      }

      if (unfolded) {
        SequenceStatement sequence = new SequenceStatement(lst);
        sequence.setAllParent();

        stat.getParent().replaceStatement(stat, sequence);

        stat = sequence;
      }
    }

    // sequence consisting of one statement -> disband
    if (stat.type == StatementType.SEQUENCE) {

      removeEmptyStatements((SequenceStatement)stat);

      if (stat.getStats().size() == 1) {

        Statement st = stat.getFirst();

        boolean ok = st.getAllSuccessorEdges().isEmpty();
        if (!ok) {
          StatEdge edge = st.getAllSuccessorEdges().get(0);

          ok = stat.getAllSuccessorEdges().isEmpty();
          if (!ok) {
            StatEdge statedge = stat.getAllSuccessorEdges().get(0);
            ok = (edge.getDestination() == statedge.getDestination());

            if (ok) {
              st.removeSuccessor(edge);
            }
          }
        }

        if (ok) {
          stat.getParent().replaceStatement(stat, st);
          stat = st;
        }
      }
    }

    // replace flat statements with synthetic basic blocks
    outer:
    while (true) {
      for (Statement st : stat.getStats()) {
        if ((st.getStats().isEmpty() || st.getExprents() != null) && st.type != StatementType.BASIC_BLOCK) {
          destroyAndFlattenStatement(st);
          continue outer;
        }
      }
      break;
    }

    // recursion
    for (int i = 0; i < stat.getStats().size(); i++) {
      condenseSequencesRec(stat.getStats().get(i));
    }
  }
private static void condenseSequencesRec(Statement stat)