    /**
     * Constructs an equivalent {@link NFA} by reducing all
     * <img src="http://cs.au.dk/~amoeller/RegAut/Lambda.gif" alt="Lambda"> transitions
     * to other transitions (and if necessary, making the initial state an accept state). [Martin, Th. 3.17]
     * The input automaton is unmodified.
     */
    public NFA removeLambdas() {
        NFA f = new NFA();
        f.alphabet = alphabet;
        Map<State,State> m = new HashMap<State,State>(); // map from old states to new states
        for (State p : states) {
            State s = (State) p.clone();
            f.states.add(s);
            m.put(p, s);
            if (accept.contains(p))
                f.accept.add(s);
        }
        f.initial = m.get(initial);
        Set<State> cl = new HashSet<State>();
        cl.add(initial);
        cl = lambdaClosure(cl);
        cl.retainAll(accept);
        if (!cl.isEmpty())
            f.accept.add(f.initial);
        for (State p : states) // this is quite naive but closely follows the mathematical definition in [Martin, Th. 3.17]
            for (char c : alphabet.symbols) {
                Set<State> set = deltaStar(p, Character.toString(c));
                Set<State> nset = new HashSet<State>();
                for (State q : set) 
                    nset.add(m.get(q));
                f.transitions.put(new StateSymbolPair(m.get(p), c), nset);
            }
        return f;
    }

