public Object visit(ArithmeticExpression node) {
            Expression left = node.getLeftExpression();
            Expression right = node.getRightExpression();

            check(left);
            check(right);

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

            if (binaryTypeCheck(node, Number.class)) {
                Type type = leftType.getCompatibleType(rightType);
                if (type.hasPrimitivePeer()) {
                    type = type.toPrimitive();

                    left.convertTo(type);
                    right.convertTo(type);
                    node.setType(type);
                }

                // one of the wrappers is not a known primitive, so maintain
                // types and let generators determine type at runtime and
                // perform operation then.  If either side is a primitive, we
                // convert to the most compatible number that can perform
                // arithmetic operations (int, long, float, double)
                else {
                    if (leftType.isPrimitive()) {
                        leftType = leftType.getCompatibleType(Type.INT_TYPE);
                        left.convertTo(leftType);
                    }

                    if (rightType.isPrimitive()) {
                        rightType = rightType.getCompatibleType(Type.INT_TYPE);
                        right.convertTo(rightType);
                    }

                    node.setType(type);
                }
            }

            return null;
        }