class CompactSequentNodes {
  long compactNodes = 0;
  long add = 0;

  public CompactSequentNodes(PegGraph pg) {
    Chain mainPegChain = pg.getMainPegChain();
    compactGraph(mainPegChain, pg);
    compactStartChain(pg);
    // PegToDotFile printer = new PegToDotFile(pg, false, "sequence");
    System.err.println("compact seq. node: " + compactNodes);
    System.err.println("number of compacting seq. nodes: " + add);
  }

  private void compactGraph(Chain chain, PegGraph peg) {
    Set canNotBeCompacted = peg.getCanNotBeCompacted();
    List<List<Object>> list = computeSequentNodes(chain, peg);
    // printSeq(list);
    Iterator<List<Object>> it = list.iterator();
    while (it.hasNext()) {
      List s = it.next();

      if (!checkIfContainsElemsCanNotBeCompacted(s, canNotBeCompacted)) {
        add++;
        compact(s, chain, peg);
      }

    }
  }

  private void compactStartChain(PegGraph graph) {<FILL_FUNCTION_BODY>}

  private List<List<Object>> computeSequentNodes(Chain chain, PegGraph pg) {
    Set<Object> gray = new HashSet<Object>();
    List<List<Object>> sequentNodes = new ArrayList<List<Object>>();

    Set canNotBeCompacted = pg.getCanNotBeCompacted();
    TopologicalSorter ts = new TopologicalSorter(chain, pg);
    ListIterator<Object> it = ts.sorter().listIterator();
    while (it.hasNext()) {
      Object node = it.next();
      List<Object> list = new ArrayList<Object>();
      if (!gray.contains(node)) {
        visitNode(pg, node, list, canNotBeCompacted, gray);
        if (list.size() > 1) {
          gray.addAll(list);
          sequentNodes.add(list);
        }

      }
    }
    return sequentNodes;
  }

  private void visitNode(PegGraph pg, Object node, List<Object> list, Set canNotBeCompacted, Set<Object> gray) {
    // System.out.println("node is: "+node);
    if (pg.getPredsOf(node).size() == 1 && pg.getSuccsOf(node).size() == 1 && !canNotBeCompacted.contains(node)
        && !gray.contains(node)) {
      list.add(node);
      Iterator it = pg.getSuccsOf(node).iterator();
      while (it.hasNext()) {
        Object o = it.next();
        visitNode(pg, o, list, canNotBeCompacted, gray);
      }

    }

    return;

  }

  private boolean checkIfContainsElemsCanNotBeCompacted(List list, Set canNotBeCompacted) {
    Iterator sccIt = list.iterator();
    while (sccIt.hasNext()) {
      Object node = sccIt.next();

      if (canNotBeCompacted.contains(node)) {
        // System.out.println("find a syn method!!");
        return true;
      }
    }
    return false;
  }

  private void compact(List list, Chain chain, PegGraph peg) {

    Iterator it = list.iterator();
    FlowSet allNodes = peg.getAllNodes();
    HashMap unitToSuccs = peg.getUnitToSuccs();
    HashMap unitToPreds = peg.getUnitToPreds();
    List<Object> newPreds = new ArrayList<Object>();
    List<Object> newSuccs = new ArrayList<Object>();

    while (it.hasNext()) {
      Object s = it.next();
      {
        Iterator predsIt = peg.getPredsOf(s).iterator();
        while (predsIt.hasNext()) {
          Object pred = predsIt.next();
          List succsOfPred = peg.getSuccsOf(pred);
          succsOfPred.remove(s);
          if (!list.contains(pred)) {
            newPreds.add(pred);
            succsOfPred.add(list);
          }
        }
      }
      {
        Iterator succsIt = peg.getSuccsOf(s).iterator();
        while (succsIt.hasNext()) {
          Object succ = succsIt.next();
          List predsOfSucc = peg.getPredsOf(succ);
          predsOfSucc.remove(s);
          if (!list.contains(succ)) {
            newSuccs.add(succ);
            predsOfSucc.add(list);
          }
        }
      }

    }
    unitToSuccs.put(list, newSuccs);
    // System.out.println("put list"+list+"\n"+ "newSuccs: "+newSuccs);
    unitToPreds.put(list, newPreds);
    allNodes.add(list);
    chain.add(list);
    updateMonitor(peg, list);
    {
      it = list.iterator();
      while (it.hasNext()) {
        Object s = it.next();
        chain.remove(s);
        allNodes.remove(s);
        unitToSuccs.remove(s);
        unitToPreds.remove(s);
      }

    }
    // System.out.println("inside compactSCC");
    // testListSucc(peg);
    compactNodes += list.size();
  }

  // The compacted nodes may inside some monitors. We need to update monitor objects.

  private void updateMonitor(PegGraph pg, List list) {
    // System.out.println("=======update monitor===");
    // add list to corresponding monitor objects sets
    Set maps = pg.getMonitor().entrySet();

    // System.out.println("---test list----");
    // testList(list);

    for (Iterator iter = maps.iterator(); iter.hasNext();) {
      Map.Entry entry = (Map.Entry) iter.next();
      FlowSet fs = (FlowSet) entry.getValue();

      Iterator it = list.iterator();
      while (it.hasNext()) {
        Object obj = it.next();
        if (fs.contains(obj)) {

          fs.add(list);
          // flag = true;
          break;
          // System.out.println("add list to monitor: "+entry.getKey());

        }

      }

    }
    // System.out.println("=======update monitor==end====");
  }
}

    Set maps = graph.getStartToThread().entrySet();
    for (Iterator iter = maps.iterator(); iter.hasNext();) {
      Map.Entry entry = (Map.Entry) iter.next();
      List runMethodChainList = (List) entry.getValue();
      Iterator it = runMethodChainList.iterator();
      while (it.hasNext()) {
        Chain chain = (Chain) it.next();
        compactGraph(chain, graph);
      }
    }

  
<no_super_class>