code: public static Object binaryOperation(
          Object obj1, Object obj2, int kind)
          throws UtilEvalError
      {
          // keep track of the original types
          Class<?> lhsOrgType = obj1.getClass();
          Class<?> rhsOrgType = obj2.getClass();
  
          // Unwrap primitives
          obj1 = Primitive.unwrap(obj1);
          obj2 = Primitive.unwrap(obj2);
  
          Object[] operands = promotePrimitives(obj1, obj2);
          Object lhs = operands[0];
          Object rhs = operands[1];
  
          if(lhs.getClass() != rhs.getClass())
              throw new UtilEvalError("Type mismatch in operator.  "
              + lhs.getClass() + " cannot be used with " + rhs.getClass() );
  
          Object result;
          try {
              result = binaryOperationImpl( lhs, rhs, kind );
          } catch ( ArithmeticException e ) {
              throw new UtilTargetError( "Arithemetic Exception in binary op", e);
          }
  
          if(result instanceof Boolean)
              return ((Boolean)result).booleanValue() ? Primitive.TRUE :
                  Primitive.FALSE;
  
          // If both original args were Primitives return a Primitive result
          // else it was mixed (wrapper/primitive) return the wrapper type
          // Exception is for boolean result, return the primitive
          if ( lhsOrgType == Primitive.class && rhsOrgType == Primitive.class )
              if ( Types.isFloatingpoint(result) && lhs.getClass() == BigDecimal.class )
                  return (Primitive) Primitive.wrap(result, result.getClass());
              else
                  return Primitive.shrinkWrap( result );
  
          return Primitive.shrinkWrap( result ).getValue();
      }
docs: Perform a binary operation on two Primitives or wrapper types.
  If both original args were Primitives return a Primitive result
  else it was mixed (wrapper/primitive) return the wrapper type.
  The exception is for boolean operations where we will return the
  primitive type either way.