private void generateEquals(Expression left, Expression right,
                                    Label label, String choice,
                                    Token operator) {

            if (right.isValueKnown() && right.getValue() == null) {
                generate(left);
                mBuilder.ifNullBranch(label, choice == "==");
            }
            else if (left.isValueKnown() && left.getValue() == null) {
                generate(right);
                mBuilder.ifNullBranch(label, choice == "==");
            }
            else {
                Method method =
                    getMethod(Object.class ,"equals", Object.class);

                Type leftType = left.getType();
                Type rightType = right.getType();

                if (leftType.isNonNull() || right.isValueKnown()) {
                    if (leftType.isNonNull()) {
                        generate(left);
                        generate(right);
                    }
                    else {
                        // Reversing the order of generation is
                        // safe because the right expression is
                        // constant.
                        generate(right);
                        generate(left);
                    }
                    setLineNumber(operator.getSourceInfo());
                    mBuilder.invoke(method);
                    mBuilder.ifZeroComparisonBranch
                        (label, (choice == "==") ? "!=" : "==");
                }
                else {
                    // This is a little bit complicated. The results
                    // of the left expression are tested against null
                    // before the equals method is invoked on it.

                    generate(left);
                    mBuilder.dup();
                    Label leftNotNull = mBuilder.createLabel();
                    mBuilder.ifNullBranch(leftNotNull, false);
                    mBuilder.pop(); // discard left expression result

                    Label fallThrough = mBuilder.createLabel();

                    if (rightType.isNonNull()) {
                        if (choice == "==") {
                            mBuilder.branch(fallThrough);
                        }
                        else {
                            mBuilder.branch(label);
                        }
                    }
                    else {
                        generate(right);
                        mBuilder.ifNullBranch(label, choice == "==");
                        mBuilder.branch(fallThrough);
                    }

                    leftNotNull.setLocation();
                    generate(right);
                    setLineNumber(operator.getSourceInfo());
                    mBuilder.invoke(method);
                    mBuilder.ifZeroComparisonBranch
                        (label, (choice == "==") ? "!=" : "==");

                    fallThrough.setLocation();
                }
            }
        }