public Object visit(CompareExpression node) {

            Expression left = node.getLeftExpression();
            Expression right = node.getRightExpression();

            // check expressions
            check(left);
            check(right);

            // determine compatibility
            Type ltype = left.getType();
            Type rtype = right.getType();

            // convert to a compatible type
            if (ltype != null && rtype != null) {

                // if both are primitive, compare directly to each other
                // otherwise, maintain types to do better analysis when
                // generating code...note that we do not do conversion of
                // primitive and wrappers to same compatible type here since
                // the generator must do branching for null checks
                if (ltype.isPrimitive() && rtype.isPrimitive()) {
                    Type compatible = ltype.getCompatibleType(rtype)
                        .getCompatibleType(Type.INT_TYPE);

                    left.convertTo(compatible);
                    right.convertTo(compatible);
                }

                // otherwise, ensure primitives are in their most valid state
                else {
                    if (ltype.isPrimitive()) {
                        Type ctype = ltype.getCompatibleType(Type.INT_TYPE);
                        if (!ltype.equals(ctype)) {
                            left.convertTo(ctype);
                        }
                    }

                    if (rtype.isPrimitive()) {
                        Type ctype = rtype.getCompatibleType(Type.INT_TYPE);
                        if (!rtype.equals(ctype)) {
                            right.convertTo(ctype);
                        }
                    }
                }

            }

            // result is -1, 0, or 1 (int)
            node.setType(Type.INT_TYPE);
            return null;
        }