class Entry<D, F> implements Numberable {
    final D data;
    int number;

    /**
     * This Entry is part of a real scc.
     */
    boolean isRealStronglyConnected;

    Entry<D, F>[] in;
    Entry<D, F>[] out;
    F inFlow;
    F outFlow;

    @SuppressWarnings("unchecked")
    Entry(D u, Entry<D, F> pred) {
      in = new Entry[] { pred };
      data = u;
      number = Integer.MIN_VALUE;
      isRealStronglyConnected = false;
    }

    @Override
    public String toString() {
      return data == null ? "" : data.toString();
    }

    @Override
    public void setNumber(int n) {
      number = n;
    }

    @Override
    public int getNumber() {
      return number;
    }
  }

  static enum Orderer {
    INSTANCE;

    /**
     * Creates a new {@code Entry} graph based on a {@code DirectedGraph}. This includes pseudo topological order, local
     * access for predecessors and successors, a graph entry-point, a {@code Numberable} interface and a real strongly
     * connected component marker.
     *
     * @param g
     * @param gv
     * @param entryFlow
     * @return
     */
    <D, F> List<Entry<D, F>> newUniverse(DirectedGraph<D> g, GraphView gv, F entryFlow, boolean isForward) {<FILL_FUNCTION_BODY>

      final int n = g.size();

      Deque<Entry<D, F>> s = new ArrayDeque<Entry<D, F>>(n);
      List<Entry<D, F>> universe = new ArrayList<Entry<D, F>>(n);
      Map<D, Entry<D, F>> visited = new HashMap<D, Entry<D, F>>(((n + 1) * 4) / 3);

      // out of universe node
      Entry<D, F> superEntry = new Entry<D, F>(null, null);

      List<D> entries = null;
      List<D> actualEntries = gv.getEntries(g);

      if (!actualEntries.isEmpty()) {
        // normal cases: there is at least
        // one return statement for a backward analysis
        // or one entry statement for a forward analysis
        entries = actualEntries;
      } else {
        // cases without any entry statement

        if (isForward) {
          // case of a forward flow analysis on
          // a method without any entry point
          throw new RuntimeException("error: no entry point for method in forward analysis");
        } else {
          // case of backward analysis on
          // a method which potentially has
          // an infinite loop and no return statement
          entries = new ArrayList<D>();

          // a single head is expected
          assert g.getHeads().size() == 1;
          D head = g.getHeads().get(0);

          // collect all 'goto' statements to catch the 'goto' from the infinite loop
          Set<D> visitedNodes = new HashSet<D>();
          List<D> workList = new ArrayList<D>();
          workList.add(head);
          for (D current; !workList.isEmpty();) {
            current = workList.remove(0);
            visitedNodes.add(current);

            // only add 'goto' statements
            if (current instanceof GotoInst || current instanceof GotoStmt) {
              entries.add(current);
            }

            for (D next : g.getSuccsOf(current)) {
              if (visitedNodes.contains(next)) {
                continue;
              }
              workList.add(next);
            }
          }

          //
          if (entries.isEmpty()) {
            throw new RuntimeException("error: backward analysis on an empty entry set.");
          }
        }
      }

      visitEntry(visited, superEntry, entries);
      superEntry.inFlow = entryFlow;
      superEntry.outFlow = entryFlow;

      @SuppressWarnings("unchecked")
      Entry<D, F>[] sv = new Entry[g.size()];
      int[] si = new int[g.size()];
      int index = 0;

      int i = 0;
      Entry<D, F> v = superEntry;

      for (;;) {
        if (i < v.out.length) {
          Entry<D, F> w = v.out[i++];

          // an unvisited child node
          if (w.number == Integer.MIN_VALUE) {
            w.number = s.size();
            s.add(w);

            visitEntry(visited, w, gv.getOut(g, w.data));

            // save old
            si[index] = i;
            sv[index] = v;
            index++;

            i = 0;
            v = w;
          }
        } else {
          if (index == 0) {
            assert universe.size() <= g.size();
            Collections.reverse(universe);
            return universe;
          }

          universe.add(v);
          sccPop(s, v);

          // restore old
          index--;
          v = sv[index];
          i = si[index];
        }
      }
    
<methods>public void <init>(DirectedGraph<N>) ,public A getFlowBefore(N) <variables>protected Map<N,A> filterUnitToBeforeFlow,protected final non-sealed DirectedGraph<N> graph,protected final non-sealed Map<N,A> unitToBeforeFlow