public String parseReference() throws IOException { 
        int c = nextNonWhitespace();
        if( c < 0 ) {
            error("Expected '$' or '%' but found end of file");
        }
        
        if( c == 'n' ) {
            // Might be a null
            int[] pos = position(-1);
            String check = "ull";
            for( int i = 0; i < check.length(); i++ ) {
                int c2 = read();
                if( c2 < 0 ) {
                    error("Unexpected end of file in reference");
                }
                if( check.charAt(i) != c2 ) {
                    // We don't know that it was meant to be a null so
                    // we'll just say bad ref.
                    error("Expected '$' or '%' but found:" + (char)c, pos);
                } 
            }
            return null; 
        }            
        if( c != '$' && c != '%' ) {
            error("Expected '$' or '%' but found:" + (char)c, position(-1));
        }

        // Keep track of our starting position because parseIdentifier
        // will wipe it out and we want to restore it upon return.
        int[] pos = position(-1).clone();        
        
        StringBuilder result = new StringBuilder();
        
        do {
            String id = parseIdentifier("reference");
            result.append((char)c);
            result.append(id);
            c = read();           
            if( c < 0 ) {
                error("Unexpected end of file in reference");
            }
        } while( c == '%' );
 
        pushBack(c);
 
        lastPos[0] = pos[0];
        lastPos[1] = pos[1];
               
        return result.toString();
    }