private HashSet<Terminal> follow1( NonTerminal nonTerminal ) {
        if( !followSets.containsKey( nonTerminal ) ) { // If follow set not calculated before
            followSets.put( nonTerminal, new HashSet<Terminal>() ); // Create a set for non-Terminal
            if( nonTerminal.equals( cfg.startSymbol ) ) { // If non-Terminal is start symbol
                followSets.get( nonTerminal ).add( cfg.endSymbol ); // Add end symbol to it's follow set
            }
        } else {
            return followSets.get( nonTerminal ); // Return already calculated follow set for non-Terminal
        }
        for( NonTerminal nonT : cfg.productions.keySet() ) { // For each non-Terminal
            for( RightHandSide rhs : cfg.productions.get( nonT ) ) { // For each right hand side for that non-Terminal
                if( rhs.contains( nonTerminal ) ) { // If right hand side contains non-Terminal then go on, if not skip
                    int idx = rhs.indexOf( nonTerminal ); // Get index of non-Terminal
                    if( idx == rhs.size() - 1 ) { // If this is the last symbol in right hand side
                        followSets.get( nonTerminal ).addAll( follow1( nonT ) ); // Add follow set of nonT to follow set of non-Terminal
                        break;
                    }
                    RightHandSide tmpRhs = new RightHandSide(); // Creates a temporary right hand side
                    tmpRhs.addAll( rhs.subList( idx + 1, rhs.size() ) ); // Puts all symbols after index into temp right hand side
                    HashSet<Terminal> tmpFirst = first( tmpRhs ); // Get first set for temp right hand side
                    followSets.get( nonTerminal ).addAll( tmpFirst ); // Add all Terminals in first set to follow set
                    if( tmpFirst.contains( cfg.terminals.get( "\0" ) ) ) { // If first set contains epsilon
                        tmpFirst.remove( cfg.terminals.get( "\0" ) ); // Remove it from first set
                        followSets.get( nonTerminal ).remove( cfg.terminals.get( "\0" ) ); // Either from follow set
                        followSets.get( nonTerminal ).addAll( follow1( nonT ) ); // Add follow set of nonT to follow set of non-Terminal
                    }
                }
            }
        }
        return followSets.get( nonTerminal );
    }