identifier           // fieldName
                );
            }
            if (this.peekKeyword("this")) {
                // '.' 'this'
                Location location = this.location();
                this.eatToken();
                return new Java.QualifiedThisReference(
                    location,                // location
                    atom.toTypeOrPE()        // qualification
                );
            }
            if (this.peekKeyword("super")) {
                Location location = this.location();
                this.eatToken();
                if (this.peekOperator("(")) {
                    // '.' 'super' Arguments
                    // Qualified superclass constructor invocation (JLS 8.8.5.1) (LHS is an Rvalue)
                    return new Java.SuperConstructorInvocation(
                        location,             // location
                        atom.toRvalueOrPE(),  // optionalQualification
                        this.parseArguments() // arguments
                    );
                }
                this.readOperator(".");
                String identifier = this.readIdentifier();
                if (this.peekOperator("(")) {
                    // '.' 'super' '.' Identifier Arguments
                    // Qualified superclass method invocation (JLS 15.12) (LHS is a ClassName)
                    // TODO: Qualified superclass method invocation
                    this.throwCompileException("Qualified superclass method invocation NYI");
                } else {
                    // '.' 'super' '.' Identifier
                    // Qualified superclass field access (JLS 15.11.2) (LHS is an Rvalue)
                    return new Java.SuperclassFieldAccessExpression(
                        location,          // location
                        atom.toTypeOrPE(), // optionalQualification
                        identifier         // fieldName
                    );
                }
            }
            if (this.peekKeyword("new")) {
                // '.' 'new' Identifier Arguments [ ClassBody ]
                Java.Rvalue lhs = atom.toRvalue();
                Location location = this.location();
                this.eatToken();
                String identifier = this.readIdentifier();
                Java.Type type = new Java.RvalueMemberType(
                    location,  // location
                    lhs,       // rValue
                    identifier // identifier
                );
                Java.Rvalue[] arguments = this.parseArguments();
                if (this.peekOperator("{")) {
                    // '.' 'new' Identifier Arguments ClassBody (LHS is an Rvalue)
                    final Java.AnonymousClassDeclaration anonymousClassDeclaration = new Java.AnonymousClassDeclaration(
                        this.location(), // location
                        type             // baseType
                    );
                    this.parseClassBody(anonymousClassDeclaration);
                    return new Java.NewAnonymousClassInstance(
                        location,                  // location
                        lhs,                       // optionalQualification
                        anonymousClassDeclaration, // anonymousClassDeclaration
                        arguments                  // arguments
                    );
                } else {
                    // '.' 'new' Identifier Arguments (LHS is an Rvalue)
                    return new Java.NewClassInstance(
                        location, // location
                        lhs,      // optionalQualification
                        type,     // referenceType
                        arguments // arguments
                    );
                }
            }
            if (this.peekKeyword("class")) {
                // '.' 'class'
                Location location = this.location();
                this.eatToken();
                return new Java.ClassLiteral(location, atom.toTypeOrPE());
            }
            this.throwCompileException("Unexpected selector \"" + this.scanner.peek() + "\" after \".\"");
        }
        if (this.peekOperator("[")) {
            // '[' Expression ']'
            Location location = this.location();
            this.eatToken();
            Java.Rvalue index = this.parseExpression().toRvalueOrPE();
            this.readOperator("]");
            return new Java.ArrayAccessExpression(
                location,        // location