# CompareOps.java

    /*
    ** Module   : CompareOps.java
    ** Abstract : Progress 4GL compatible CompareOps object
    **
    ** Copyright (c) 2005-2025, Golden Code Development Corporation.
    **
    ** -#- -I- --Date-- --JPRM-- -----------------------------Description-----------------------------
    ** 001 GES 20050519   @21247 Created initial version with full support for all Progress comparison
    **                           processing including all functions and logical operators.
    ** 002 GES 20050607   @21441 Minor additions for function support.
    ** 003 GES 20060303   @24881 Added unknown value helpers.
    ** 004 GES 20060620   @27477 Fixed unknown value processing for greater than and less than
    **                           operators. Massive updates to the javadoc to fully document the
    **                           behavior.
    ** 005 SIY 20070911   @35038 Workaround for some cases of string comparison for equality
    **                           (unknown vs "?"). Ref: 35039.
    ** 006 GES 20080402   @37824 Added signatures to allow widget references to be compared with
    **                           handle types and each other.
    ** 007 GES 20081003   @40034 Added signatures for operators which can return boolean instead of
    **                           logical, where those signatures were missing.
    ** 008 CA  20090227   @41384 Added _isUnknown(String) method - return true if parameter is null.
    ** 009 CA  20090413   @41783 Added isUnknown(String) method, which returns Progress logical true
    **                           if parameter is null. Minor cleanup.
    ** 010 OM  20130402   @41783 Switched to 64-bit long instead of 32 bit int.
    ** 011 OM  20150415          Rollback H005. Behavior was the result of LITERAL-QUESTION attribute.
    ** 012 VVT 20191119          Special case: an empty comhandle is considered be equal to the zero
    **                           integer. See #3820-170.
    ** 013 CA  20200304          Allow unknown tests for Java instances from 4GL code.
    ** 014 CA  20220620          Any equality compare between a legacy Text (longchar/character) instance and
    **                           another type will force compare as character.
    ** 015 CA  20231129          Avoid additional BDT creation for some operators which receive Java arguments.
    ** 016 CA  20240324          Use logical constants for TRUE, FALSE, UNKNOWN, within internal FWD runtime.
    ** 017 ICP 20250129          Used int64.of to leverage caches instances.
    */
    /*
    ** This program is free software: you can redistribute it and/or modify
    ** it under the terms of the GNU Affero General Public License as
    ** published by the Free Software Foundation, either version 3 of the
    ** License, or (at your option) any later version.
    **
    ** This program is distributed in the hope that it will be useful,
    ** but WITHOUT ANY WARRANTY; without even the implied warranty of
    ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    ** GNU Affero General Public License for more details.
    **
    ** You may find a copy of the GNU Affero GPL version 3 at the following
    ** location: https://www.gnu.org/licenses/agpl-3.0.en.html
    **
    ** Additional terms under GNU Affero GPL version 3 section 7:
    **
    **   Under Section 7 of the GNU Affero GPL version 3, the following additional
    **   terms apply to the works covered under the License.  These additional terms
    **   are non-permissive additional terms allowed under Section 7 of the GNU
    **   Affero GPL version 3 and may not be removed by you.
    **
    **   0. Attribution Requirement.
    **
    **     You must preserve all legal notices or author attributions in the covered
    **     work or Appropriate Legal Notices displayed by works containing the covered
    **     work.  You may not remove from the covered work any author or developer
    **     credit already included within the covered work.
    **
    **   1. No License To Use Trademarks.
    **
    **     This license does not grant any license or rights to use the trademarks
    **     Golden Code, FWD, any Golden Code or FWD logo, or any other trademarks
    **     of Golden Code Development Corporation. You are not authorized to use the
    **     name Golden Code, FWD, or the names of any author or contributor, for
    **     publicity purposes without written authorization.
    **
    **   2. No Misrepresentation of Affiliation.
    **
    **     You may not represent yourself as Golden Code Development Corporation or FWD.
    **
    **     You may not represent yourself for publicity purposes as associated with
    **     Golden Code Development Corporation, FWD, or any author or contributor to
    **     the covered work, without written authorization.
    **
    **   3. No Misrepresentation of Source or Origin.
    **
    **     You may not represent the covered work as solely your work.  All modified
    **     versions of the covered work must be marked in a reasonable way to make it
    **     clear that the modified work is not originating from Golden Code Development
    **     Corporation or FWD.  All modified versions must contain the notices of
    **     attribution required in this license.
    */

    package com.goldencode.p2j.util;

    /**
     * A class that provides Progress 4GL compatible comparison functions and
     * logical operators.  This class provides all functionality as statics and
     * has no instance data.
     * <p>
     * The following is the mapping of Progress language features to the
     * corresponding feature in this class:
     * <p>
     * <pre>
     * =  or EQ operator                       {@link #isEqual}
     * &lt;&gt; or NE operator                       {@link #isNotEqual}
     * &gt;  or GT operator                       {@link #isGreaterThan}
     * &gt;= or GE operator                       {@link #isGreaterThanOrEqual}
     * &lt;  or LT operator                       {@link #isLessThan}
     * &lt;= or LE operator                       {@link #isLessThanOrEqual}
     * maximum  function                       {@link #maximum(BaseDataType[])}
     * minimum  function                       {@link #minimum(BaseDataType[])}
     * </pre>
     * <p>
     * The above methods all return an instance of {@link logical} which allows
     * the Progress unknown value to be properly handled.  Each method is
     * heavily overloaded to support the possible variants of Java primitive
     * types as parameters.  A duplicate version of each of the operators
     * exists under a name without the 'is' prefix, which returns
     * <code>boolean</code> as a convenience (WARNING: these duplicates
     * do not have all overloaded variants to support all primitive types as
     * do the versions that return a <code>logical</code>).
     * <p>
     * This class implements common unknown value logic for all operators and
     * functions, which is summarized by the following table of results (whether
     * the unknown value is in the left or right operand makes no difference):
     * <p>
     * <pre>
     * Operator                One Operand Unknown       Both Operands Unknown
     * --------------------    ---------------------     ----------------------
     * isEqual                 false                     true
     * isNotEqual              true                      false
     * isGreaterThan           unknown value             false
     * isLessThan              unknown value             false
     * isGreaterThanOrEqual    unknown value             true
     * isLessThanOrEqual       unknown value             true
     * </pre>
     * <p>
     * If any parameter of the {@link #minimum} or {@link #maximum} methods
     * is unknown, the result is unknown.
     * <p>
     * Helper methods exist to test if an instance is <code>unknown</code>
     * {@link #isUnknown} (and {@link #_isUnknown}) or is not <code>unknown</code>
     * {@link #notUnknown} (and {@link #_notUnknown}). They return a
     * <code>logical</code> or <code>boolean</code> type which makes them a
     * simpler form to use in expressions instead of
     * <code>isEqual(new unknown())</code>.
     *
     * @author    GES
     */
    public class CompareOps
    {
       /**
        * Returns the instance from the list which is the largest.  This
        * list may not include <code>null</code> values and all values must
        * be of the same subclass in order for the results to make sense.
        *
        * @param    list
        *           The list of objects to check.
        *
        * @return   The largest instance or an instance of
        *           <code>unknown value</code> if any entry in the list is
        *           unknown or <code>null</code> if an empty list is passed.
        */
       public static BaseDataType maximum(BaseDataType[] list)
       {
          if (list.length == 0)
          {
             return null;
          }

          BaseDataType largest = list[0];

          for (int i = 1; i < list.length; i++)
          {
             largest = largest.maximum(list[i]);
          }

          return largest;
       }

       /**
        * Returns the smallest instance from the list.  This list may not
        * include <code>null</code> values and all values must
        * be of the same subclass in order for the results to make sense.
        *
        * @param    list
        *           The list of objects to check.
        *
        * @return   The smallest instance or an instance of
        *           <code>unknown value</code> if any entry in the list is
        *           unknown or <code>null</code> if an empty list is passed.
        */
       public static BaseDataType minimum(BaseDataType[] list)
       {
          if (list.length == 0)
          {
             return null;
          }

          BaseDataType smallest = list[0];

          for (int i = 1; i < list.length; i++)
          {
             smallest = smallest.minimum(list[i]);
          }

          return smallest;
       }

       /**
        * Determines if the operand represents the <code>unknown value</code>.
        *
        * @param    op
        *           The instance to test.
        *
        * @return   <code>true</code> if the object is <code>unknown</code>.
        */
       public static boolean _isUnknown(BaseDataType op)
       {
          return op.isUnknown();
       }

       /**
        * Determines if the operand represents the <code>unknown value</code>.
        * For a <code>null</code> value, this method will return true.
        *
        * @param    op
        *           The instance to test.
        *
        * @return   <code>true</code> if the object is <code>unknown</code>.
        */
       public static boolean _isUnknown(String op)
       {
          return op == null;
       }

       /**
        * Determines if the operand represents the <code>unknown value</code>.
        *
        * @param    op
        *           The instance to test.
        *
        * @return   <code>true</code> if the object is <code>unknown</code>.
        */
       public static boolean _isUnknown(WrappedResource op)
       {
          return op == null || op.unknown();
       }

       /**
        * Determines if the operand represents the <code>unknown value</code>.
        *
        * @param    op
        *           The instance to test.
        *
        * @return   Logical <code>true</code> if the object is
        *           <code>unknown</code>.
        */
       public static logical isUnknown(BaseDataType op)
       {
          return logical.of(op.isUnknown());
       }

       /**
        * Determines if the operand represents the <code>unknown value</code>.
        *
        * @param    op
        *           The instance to test.
        *
        * @return   Logical <code>true</code> if the object is
        *           <code>unknown</code>.
        */
       public static logical isUnknown(WrappedResource op)
       {
          return isUnknown(new handle(op));
       }

       /**
        * Determines if the operand represents the <code>unknown value</code>.
        * For a <code>null</code> value, this method will return true.
        *
        * @param    op
        *           The instance to test.
        *
        * @return   <code>true</code> if the object is <code>unknown</code>.
        */
       public static logical isUnknown(String op)
       {
          return logical.of(op == null);
       }

       /**
        * For a <code>null</code> value, this method will return true.
        *
        * @param    op
        *           The instance to test.
        *
        * @return   <code>true</code> if the object is <code>null</code>.
        */
       public static logical isUnknown(Object op)
       {
          return logical.of(op == null);
       }

       /**
        * Determines if the operand does NOT represent the
        * <code>unknown value</code>.
        *
        * @param    op
        *           The instance to test.
        *
        * @return   <code>true</code> if the object is NOT <code>unknown</code>.
        */
       public static boolean _notUnknown(BaseDataType op)
       {
          return !op.isUnknown();
       }

       /**
        * Determines if the operand does NOT represent the
        * <code>unknown value</code>.
        *
        * @param    op
        *           The instance to test.
        *
        * @return   <code>true</code> if the object is NOT <code>unknown</code>.
        */
       public static boolean _notUnknown(WrappedResource op)
       {
          return op != null && !op.unknown();
       }

       /**
        * Determines if the operand does NOT represent the
        * <code>null value</code>.
        *
        * @param    op
        *           The instance to test.
        *
        * @return   <code>true</code> if the object is NOT <code>null</code>.
        */
       public static boolean _notUnknown(Object op)
       {
          return op != null;
       }

       /**
        * Determines if the operand does NOT represent the
        * <code>unknown value</code>.
        *
        * @param    op
        *           The instance to test.
        *
        * @return   Logical <code>true</code> if the object is NOT
        *           <code>unknown</code>.
        */
       public static logical notUnknown(BaseDataType op)
       {
          return logical.of(!op.isUnknown());
       }

       /**
        * Determines if the operand does NOT represent the
        * <code>unknown value</code>.
        *
        * @param    op
        *           The instance to test.
        *
        * @return   Logical <code>true</code> if the object is NOT
        *           <code>unknown</code>.
        */
       public static logical notUnknown(WrappedResource op)
       {
          return notUnknown(new handle(op));
       }

       /**
        * Determines if the operand does NOT represent the
        * <code>null value</code>.
        *
        * @param    op
        *           The instance to test.
        *
        * @return   Logical <code>true</code> if the object is NOT
        *           <code>null</code>.
        */
       public static logical notUnknown(Object op)
       {
          return logical.of(op != null);
       }

       /**
        * Determines if the two operands are equivalent.
        *
        * @param   op1
        *          The left operand.
        * @param   op2
        *          The right operand.
        *
        * @return  {@code true} if the operands are the same or if both operands are {@code unknown}.
        */
       public static boolean equals(BaseDataType op1, BaseDataType op2)
       {
          boolean u1 = op1.isUnknown();
          boolean u2 = op2.isUnknown();

          // special case: an empty comhandle is considered be equal to the zero integer
          if ((u1 && !u2 && (op1 instanceof comhandle) && (op2 instanceof int64)
                  && ((int64) op2).getValue() == 0L) ||
              (u2 && !u1 && (op2 instanceof comhandle) && (op1 instanceof int64)
                  && ((int64) op1).getValue() == 0L))
          {
             return true;
          }

          if (u1 && u2)
          {
             return true;
          }

          if (u1 || u2)
          {
             return false;
          }

          if (op2 instanceof Text && !(op1 instanceof Text))
          {
             // compare string representation
             return equals(new character(op1), op2);
          }

          if (op1 instanceof Text && !(op2 instanceof Text))
          {
             // compare string representation
             return equals(op1, new character(op2));
          }

          return op1.compareTo(op2) == 0;
       }

       /**
        * Determines if the two operands are equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the operands are the same or if both
        *           operands are <code>unknown</code>.
        */
       public static boolean _isEqual(BaseDataType op1, BaseDataType op2)
       {
          return equals(op1, op2);
       }

       /**
        * Determines if the two operands are equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the operands are the same or if both
        *           operands are <code>unknown</code>.
        */
       public static boolean _isEqual(WrappedResource op1, BaseDataType op2)
       {
          return equals(new handle(op1), op2);
       }

       /**
        * Determines if the two operands are equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the operands are the same or if both
        *           operands are <code>unknown</code>.
        */
       public static boolean _isEqual(BaseDataType op1, WrappedResource op2)
       {
          return equals(op1, new handle(op2));
       }

       /**
        * Determines if the two operands are equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the operands are the same or if both
        *           operands are <code>unknown</code>.
        */
       public static boolean _isEqual(WrappedResource op1, WrappedResource op2)
       {
          return equals(new handle(op1), new handle(op2));
       }

       /**
        * Determines if the two operands are equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the operands are the same.
        */
       public static boolean _isEqual(boolean op1, BaseDataType op2)
       {
          return equals(logical.of(op1), op2);
       }

       /**
        * Determines if the two operands are equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the operands are the same.
        */
       public static boolean _isEqual(BaseDataType op1, boolean op2)
       {
          return equals(op1, logical.of(op2));
       }

       /**
        * Determines if the two operands are equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the operands are the same.
        */
       public static boolean _isEqual(boolean op1, boolean op2)
       {
          // INLINED for efficiency...
          return (op1 == op2);
       }

       /**
        * Determines if the two operands are equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the operands are the same.
        */
       public static boolean _isEqual(String op1, BaseDataType op2)
       {
          return equals(new character(op1), op2);
       }

       /**
        * Determines if the two operands are equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the operands are the same.
        */
       public static boolean _isEqual(BaseDataType op1, String op2)
       {
          return equals(op1, new character(op2));
       }

       /**
        * Determines if the two operands are equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the operands are the same.
        */
       public static boolean _isEqual(String op1, String op2)
       {
          // INLINED for efficiency...

          // DO NOT use String.compareToIgnoreCase() since this lowercases
          // and yields different results for >, <, >= and <= forms when
          // [ \ ^ _ ' characters are included in the operands
          int result = op1.toUpperCase().compareTo(op2.toUpperCase());

          return (result == 0);
       }

       /**
        * Determines if the two operands are equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the operands are the same.
        */
       public static boolean _isEqual(long op1, BaseDataType op2)
       {
          return equals(int64.of(op1), op2);
       }

       /**
        * Determines if the two operands are equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the operands are the same.
        */
       public static boolean _isEqual(BaseDataType op1, long op2)
       {
          return equals(op1, int64.of(op2));
       }

       /**
        * Determines if the two operands are equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the operands are the same.
        */
       public static boolean _isEqual(long op1, long op2)
       {
          // INLINED for efficiency...
          return (op1 == op2);
       }

       /**
        * Determines if the two operands are equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the operands are the same.
        */
       public static boolean _isEqual(double op1, BaseDataType op2)
       {
          return equals(new decimal(op1), op2);
       }

       /**
        * Determines if the two operands are equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the operands are the same.
        */
       public static boolean _isEqual(BaseDataType op1, double op2)
       {
          return equals(op1, new decimal(op2));
       }

       /**
        * Determines if the two operands are equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the operands are the same.
        */
       public static boolean _isEqual(double op1, double op2)
       {
          // also matches int == double and double == int cases
          return equals(new decimal(op1), new decimal(op2));
       }

       /**
        * Determines if the two operands are equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the operands are the same or if both
        *           operands are <code>unknown</code>.
        */
       public static logical isEqual(BaseDataType op1, BaseDataType op2)
       {
          return logical.of(equals(op1, op2));
       }

       /**
        * Determines if the two operands are equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the operands are the same or if both
        *           operands are <code>unknown</code>.
        */
       public static logical isEqual(WrappedResource op1, BaseDataType op2)
       {
          return logical.of(equals(new handle(op1), op2));
       }

       /**
        * Determines if the two operands are equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the operands are the same or if both
        *           operands are <code>unknown</code>.
        */
       public static logical isEqual(BaseDataType op1, WrappedResource op2)
       {
          return logical.of(equals(op1, new handle(op2)));
       }

       /**
        * Determines if the two operands are equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the operands are the same or if both
        *           operands are <code>unknown</code>.
        */
       public static logical isEqual(WrappedResource op1, WrappedResource op2)
       {
          return logical.of(equals(new handle(op1), new handle(op2)));
       }

       /**
        * Determines if the two operands are equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the operands are the same.
        */
       public static logical isEqual(boolean op1, BaseDataType op2)
       {
          return logical.of(equals(logical.of(op1), op2));
       }

       /**
        * Determines if the two operands are equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the operands are the same.
        */
       public static logical isEqual(BaseDataType op1, boolean op2)
       {
          return logical.of(equals(op1, logical.of(op2)));
       }

       /**
        * Determines if the two operands are equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the operands are the same.
        */
       public static logical isEqual(boolean op1, boolean op2)
       {
          // INLINED for efficiency...
          return logical.of(op1 == op2);
       }

       /**
        * Determines if the two operands are equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the operands are the same.
        */
       public static logical isEqual(String op1, BaseDataType op2)
       {
          return logical.of(equals(new character(op1), op2));
       }

       /**
        * Determines if the two operands are equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the operands are the same.
        */
       public static logical isEqual(BaseDataType op1, String op2)
       {
          return logical.of(equals(op1, new character(op2)));
       }

       /**
        * Determines if the two operands are equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the operands are the same.
        */
       public static logical isEqual(String op1, String op2)
       {
          // INLINED for efficiency...

          // DO NOT use String.compareToIgnoreCase() since this lowercases
          // and yields different results for >, <, >= and <= forms when
          // [ \ ^ _ ' characters are included in the operands
          int result = op1.toUpperCase().compareTo(op2.toUpperCase());

          return logical.of(result == 0);
       }

       /**
        * Determines if the two operands are equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the operands are the same.
        */
       public static logical isEqual(long op1, BaseDataType op2)
       {
          return logical.of(equals(int64.of(op1), op2));
       }

       /**
        * Determines if the two operands are equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the operands are the same.
        */
       public static logical isEqual(BaseDataType op1, long op2)
       {
          return logical.of(equals(op1, int64.of(op2)));
       }

       /**
        * Determines if the two operands are equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the operands are the same.
        */
       public static logical isEqual(long op1, long op2)
       {
          // INLINED for efficiency...
          return logical.of(op1 == op2);
       }

       /**
        * Determines if the two operands are equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the operands are the same.
        */
       public static logical isEqual(double op1, BaseDataType op2)
       {
          return logical.of(equals(new decimal(op1), op2));
       }

       /**
        * Determines if the two operands are equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the operands are the same.
        */
       public static logical isEqual(BaseDataType op1, double op2)
       {
          return logical.of(equals(op1, new decimal(op2)));
       }

       /**
        * Determines if the two operands are equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the operands are the same.
        */
       public static logical isEqual(double op1, double op2)
       {
          // also matches int == double and double == int cases
          return logical.of(equals(new decimal(op1), new decimal(op2)));
       }

       /**
        * Determines if the two operands are <b>not</b> equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the objects are <b>not</b> the same OR
        *           if either of the operands is <code>unknown</code> while the
        *           other is not.
        */
       public static boolean notEqual(BaseDataType op1, BaseDataType op2)
       {
          return !equals(op1, op2);
       }

       /**
        * Determines if the two operands are <b>not</b> equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the objects are <b>not</b> the same OR
        *           if either of the operands is <code>unknown</code> while the
        *           other is not.
        */
       public static boolean _isNotEqual(BaseDataType op1, BaseDataType op2)
       {
          return notEqual(op1, op2);
       }

       /**
        * Determines if the two operands are <b>not</b> equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the objects are <b>not</b> the same OR
        *           if either of the operands is <code>unknown</code> while the
        *           other is not.
        */
       public static boolean _isNotEqual(WrappedResource op1, BaseDataType op2)
       {
          return notEqual(new handle(op1), op2);
       }

       /**
        * Determines if the two operands are <b>not</b> equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the objects are <b>not</b> the same OR
        *           if either of the operands is <code>unknown</code> while the
        *           other is not.
        */
       public static boolean _isNotEqual(BaseDataType op1, WrappedResource op2)
       {
          return notEqual(op1, new handle(op2));
       }

       /**
        * Determines if the two operands are <b>not</b> equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the objects are <b>not</b> the same OR
        *           if either of the operands is <code>unknown</code> while the
        *           other is not.
        */
       public static boolean _isNotEqual(WrappedResource op1, WrappedResource op2)
       {
          return notEqual(new handle(op1), new handle(op2));
       }

       /**
        * Determines if the two operands are <b>not</b> equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the objects are <b>not</b> the same OR
        *           if the right operand is <code>unknown</code>.
        */
       public static boolean _isNotEqual(boolean op1, BaseDataType op2)
       {
          return notEqual(logical.of(op1), op2);
       }

       /**
        * Determines if the two operands are <b>not</b> equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the objects are <b>not</b> the same OR
        *           if the left operand is <code>unknown</code>.
        */
       public static boolean _isNotEqual(BaseDataType op1, boolean op2)
       {
          return notEqual(op1, logical.of(op2));
       }

       /**
        * Determines if the two operands are <b>not</b> equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the objects are <b>not</b> the same.
        */
       public static boolean _isNotEqual(boolean op1, boolean op2)
       {
          // INLINED for efficiency...
          return (op1 != op2);
       }

       /**
        * Determines if the two operands are <b>not</b> equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the objects are <b>not</b> the same OR
        *           if the right operand is <code>unknown</code>.
        */
       public static boolean _isNotEqual(String op1, BaseDataType op2)
       {
          return notEqual(new character(op1), op2);
       }

       /**
        * Determines if the two operands are <b>not</b> equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the objects are <b>not</b> the same OR
        *           if the left operand is <code>unknown</code>.
        */
       public static boolean _isNotEqual(BaseDataType op1, String op2)
       {
          return notEqual(op1, new character(op2));
       }

       /**
        * Determines if the two operands are <b>not</b> equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the objects are <b>not</b> the same.
        */
       public static boolean _isNotEqual(String op1, String op2)
       {
          // INLINED for efficiency...

          // DO NOT use String.compareToIgnoreCase() since this lowercases
          // and yields different results for >, <, >= and <= forms when
          // [ \ ^ _ ' characters are included in the operands
          int result = op1.toUpperCase().compareTo(op2.toUpperCase());

          return (result != 0);
       }

       /**
        * Determines if the two operands are <b>not</b> equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the objects are <b>not</b> the same OR
        *           if the right operand is <code>unknown</code>.
        */
       public static boolean _isNotEqual(long op1, BaseDataType op2)
       {
          return notEqual(int64.of(op1), op2);
       }

       /**
        * Determines if the two operands are <b>not</b> equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the objects are <b>not</b> the same OR
        *           if the left operand is <code>unknown</code>.
        */
       public static boolean _isNotEqual(BaseDataType op1, long op2)
       {
          return notEqual(op1, int64.of(op2));
       }

       /**
        * Determines if the two operands are <b>not</b> equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the objects are <b>not</b> the same.
        */
       public static boolean _isNotEqual(long op1, long op2)
       {
          // INLINED for efficiency...
          return (op1 != op2);
       }

       /**
        * Determines if the two operands are <b>not</b> equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the objects are <b>not</b> the same OR
        *           if the right operand is <code>unknown</code>.
        */
       public static boolean _isNotEqual(double op1, BaseDataType op2)
       {
          return notEqual(new decimal(op1), op2);
       }

       /**
        * Determines if the two operands are <b>not</b> equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the objects are <b>not</b> the same OR
        *           if the left operand is <code>unknown</code>.
        */
       public static boolean _isNotEqual(BaseDataType op1, double op2)
       {
          return notEqual(op1, new decimal(op2));
       }

       /**
        * Determines if the two operands are <b>not</b> equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the objects are <b>not</b> the same.
        */
       public static boolean _isNotEqual(double op1, double op2)
       {
          // also matches the double != int and int != double cases
          return notEqual(new decimal(op1), new decimal(op2));
       }

       /**
        * Determines if the two operands are <b>not</b> equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the objects are <b>not</b> the same OR
        *           if either of the operands is <code>unknown</code> while the
        *           other is not.
        */
       public static logical isNotEqual(BaseDataType op1, BaseDataType op2)
       {
          return logical.of(notEqual(op1, op2));
       }

       /**
        * Determines if the two operands are <b>not</b> equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the objects are <b>not</b> the same OR
        *           if either of the operands is <code>unknown</code> while the
        *           other is not.
        */
       public static logical isNotEqual(WrappedResource op1, BaseDataType op2)
       {
          return logical.of(notEqual(new handle(op1), op2));
       }

       /**
        * Determines if the two operands are <b>not</b> equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the objects are <b>not</b> the same OR
        *           if either of the operands is <code>unknown</code> while the
        *           other is not.
        */
       public static logical isNotEqual(BaseDataType op1, WrappedResource op2)
       {
          return logical.of(notEqual(op1, new handle(op2)));
       }

       /**
        * Determines if the two operands are <b>not</b> equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the objects are <b>not</b> the same OR
        *           if either of the operands is <code>unknown</code> while the
        *           other is not.
        */
       public static logical isNotEqual(WrappedResource op1, WrappedResource op2)
       {
          return logical.of(notEqual(new handle(op1), new handle(op2)));
       }

       /**
        * Determines if the two operands are <b>not</b> equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the objects are <b>not</b> the same OR
        *           if the right operand is <code>unknown</code>.
        */
       public static logical isNotEqual(boolean op1, BaseDataType op2)
       {
          return logical.of(notEqual(logical.of(op1), op2));
       }

       /**
        * Determines if the two operands are <b>not</b> equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the objects are <b>not</b> the same OR
        *           if the left operand is <code>unknown</code>.
        */
       public static logical isNotEqual(BaseDataType op1, boolean op2)
       {
          return logical.of(notEqual(op1, logical.of(op2)));
       }

       /**
        * Determines if the two operands are <b>not</b> equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the objects are <b>not</b> the same.
        */
       public static logical isNotEqual(boolean op1, boolean op2)
       {
          // INLINED for efficiency...
          return logical.of(op1 != op2);
       }

       /**
        * Determines if the two operands are <b>not</b> equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the objects are <b>not</b> the same OR
        *           if the right operand is <code>unknown</code>.
        */
       public static logical isNotEqual(String op1, BaseDataType op2)
       {
          return logical.of(notEqual(new character(op1), op2));
       }

       /**
        * Determines if the two operands are <b>not</b> equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the objects are <b>not</b> the same OR
        *           if the left operand is <code>unknown</code>.
        */
       public static logical isNotEqual(BaseDataType op1, String op2)
       {
          return logical.of(notEqual(op1, new character(op2)));
       }

       /**
        * Determines if the two operands are <b>not</b> equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the objects are <b>not</b> the same.
        */
       public static logical isNotEqual(String op1, String op2)
       {
          // INLINED for efficiency...

          // DO NOT use String.compareToIgnoreCase() since this lowercases
          // and yields different results for >, <, >= and <= forms when
          // [ \ ^ _ ' characters are included in the operands
          int result = op1.toUpperCase().compareTo(op2.toUpperCase());

          return logical.of(result != 0);
       }

       /**
        * Determines if the two operands are <b>not</b> equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the objects are <b>not</b> the same OR
        *           if the right operand is <code>unknown</code>.
        */
       public static logical isNotEqual(long op1, BaseDataType op2)
       {
          return logical.of(notEqual(int64.of(op1), op2));
       }

       /**
        * Determines if the two operands are <b>not</b> equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the objects are <b>not</b> the same OR
        *           if the left operand is <code>unknown</code>.
        */
       public static logical isNotEqual(BaseDataType op1, long op2)
       {
          return logical.of(notEqual(op1, int64.of(op2)));
       }

       /**
        * Determines if the two operands are <b>not</b> equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the objects are <b>not</b> the same.
        */
       public static logical isNotEqual(long op1, long op2)
       {
          // INLINED for efficiency...
          return logical.of(op1 != op2);
       }

       /**
        * Determines if the two operands are <b>not</b> equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the objects are <b>not</b> the same OR
        *           if the right operand is <code>unknown</code>.
        */
       public static logical isNotEqual(double op1, BaseDataType op2)
       {
          return logical.of(notEqual(new decimal(op1), op2));
       }

       /**
        * Determines if the two operands are <b>not</b> equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the objects are <b>not</b> the same OR
        *           if the left operand is <code>unknown</code>.
        */
       public static logical isNotEqual(BaseDataType op1, double op2)
       {
          return logical.of(notEqual(op1, new decimal(op2)));
       }

       /**
        * Determines if the two operands are <b>not</b> equivalent.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the objects are <b>not</b> the same.
        */
       public static logical isNotEqual(double op1, double op2)
       {
          // also matches the double != int and int != double cases
          return logical.of(notEqual(new decimal(op1), new decimal(op2)));
       }

       /**
        * Determines if the left operand is greater than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than the
        *           right operand. <code>false</code> if the left operand
        *           is less than or equal to the right operand OR when either
        *           or both of the operands are <code>unknown</code>.
        */
       public static boolean greaterThan(BaseDataType op1, BaseDataType op2)
       {
          boolean u1 = op1.isUnknown();
          boolean u2 = op2.isUnknown();

          if (u1 || u2)
             return false;

          return (op1.compareTo(op2) > 0);
       }

       /**
        * Determines if the left operand is greater than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than the
        *           right operand. <code>false</code> if the left operand
        *           is less than or equal to the right operand OR if either or
        *           both operands are <code>unknown</code>.
        */
       public static boolean _isGreaterThan(BaseDataType op1, BaseDataType op2)
       {
          return greaterThan(op1, op2);
       }

       /**
        * Determines if the left operand is greater than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than the
        *           right operand. <code>false</code> if the left operand
        *           is less than or equal to the right operand or when the right
        *           operand is <code>unknown</code>.
        */
       public static boolean _isGreaterThan(boolean op1, BaseDataType op2)
       {
          return greaterThan(logical.of(op1), op2);
       }

       /**
        * Determines if the left operand is greater than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than the
        *           right operand. <code>false</code> if the left operand
        *           is less than or equal to the right operand or when the left
        *           operand is <code>unknown</code>.
        */
       public static boolean _isGreaterThan(BaseDataType op1, boolean op2)
       {
          return greaterThan(op1, logical.of(op2));
       }

       /**
        * Determines if the left operand is greater than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than the
        *           right operand. <code>false</code> if the left operand
        *           is less than or equal to the right operand.
        */
       public static boolean _isGreaterThan(boolean op1, boolean op2)
       {
          return greaterThan(logical.of(op1), logical.of(op2));
       }

       /**
        * Determines if the left operand is greater than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than the
        *           right operand. <code>false</code> if the left operand
        *           is less than or equal to the right operand or when the right
        *           operand is <code>unknown</code>.
        */
       public static boolean _isGreaterThan(String op1, BaseDataType op2)
       {
          return greaterThan(new character(op1), op2);
       }

       /**
        * Determines if the left operand is greater than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than the
        *           right operand. <code>false</code> if the left operand
        *           is less than or equal to the right operand or when the left
        *           operand is <code>unknown</code>.
        */
       public static boolean _isGreaterThan(BaseDataType op1, String op2)
       {
          return greaterThan(op1, new character(op2));
       }

       /**
        * Determines if the left operand is greater than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than the
        *           right operand. <code>false</code> if the left operand
        *           is less than or equal to the right operand.
        */
       public static boolean _isGreaterThan(String op1, String op2)
       {
          // INLINED for efficiency...

          // DO NOT use String.compareToIgnoreCase() since this lowercases
          // and yields different results for >, <, >= and <= forms when
          // [ \ ^ _ ' characters are included in the operands
          int result = op1.toUpperCase().compareTo(op2.toUpperCase());

          return (result > 0);
       }

       /**
        * Determines if the left operand is greater than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than the
        *           right operand. <code>false</code> if the left operand
        *           is less than or equal to the right operand or when the right
        *           operand is <code>unknown</code>.
        */
       public static boolean _isGreaterThan(long op1, BaseDataType op2)
       {
          return greaterThan(new int64(op1), op2);
       }

       /**
        * Determines if the left operand is greater than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than the
        *           right operand. <code>false</code> if the left operand
        *           is less than or equal to the right operand or when the left
        *           operand is <code>unknown</code>.
        */
       public static boolean _isGreaterThan(BaseDataType op1, long op2)
       {
          return greaterThan(op1, int64.of(op2));
       }

       /**
        * Determines if the left operand is greater than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than the
        *           right operand. <code>false</code> if the left operand
        *           is less than or equal to the right operand.
        */
       public static boolean _isGreaterThan(long op1, long op2)
       {
          // INLINED for efficiency...
          return (op1 > op2);
       }

       /**
        * Determines if the left operand is greater than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than the
        *           right operand. <code>false</code> if the left operand
        *           is less than or equal to the right operand or when the right
        *           operand is <code>unknown</code>.
        */
       public static boolean _isGreaterThan(double op1, BaseDataType op2)
       {
          return greaterThan(new decimal(op1), op2);
       }

       /**
        * Determines if the left operand is greater than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than the
        *           right operand. <code>false</code> if the left operand
        *           is less than or equal to the right operand or when the left
        *           operand is <code>unknown</code>.
        */
       public static boolean _isGreaterThan(BaseDataType op1, double op2)
       {
          return greaterThan(op1, new decimal(op2));
       }

       /**
        * Determines if the left operand is greater than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than the
        *           right operand. <code>false</code> if the left operand
        *           is less than or equal to the right operand.
        */
       public static boolean _isGreaterThan(double op1, double op2)
       {
          // also handles double > int and int > double cases
          return greaterThan(new decimal(op1), new decimal(op2));
       }

       /**
        * Determines if the left operand is greater than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than the
        *           right operand. <code>false</code> if the left operand
        *           is less than or equal to the right operand OR if both
        *           operands are <code>unknown</code>.  <code>unknown</code>
        *           when any one operand is <code>unknown</code> and the other
        *           is not.
        */
       public static logical isGreaterThan(BaseDataType op1, BaseDataType op2)
       {
          boolean u1 = op1.isUnknown();
          boolean u2 = op2.isUnknown();

          if (u1 && u2)
             return logical.of(false);

          if (u1 || u2)
             return logical.UNKNOWN;

          return logical.of(op1.compareTo(op2) > 0);
       }

       /**
        * Determines if the left operand is greater than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than the
        *           right operand. <code>false</code> if the left operand
        *           is less than or equal to the right operand.
        *           <code>unknown</code> when the right operand is
        *           <code>unknown</code>.
        */
       public static logical isGreaterThan(boolean op1, BaseDataType op2)
       {
          return isGreaterThan(logical.of(op1), op2);
       }

       /**
        * Determines if the left operand is greater than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than the
        *           right operand. <code>false</code> if the left operand
        *           is less than or equal to the right operand.
        *           <code>unknown</code> when the left operand is
        *           <code>unknown</code>.
        */
       public static logical isGreaterThan(BaseDataType op1, boolean op2)
       {
          return isGreaterThan(op1, logical.of(op2));
       }

       /**
        * Determines if the left operand is greater than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than the
        *           right operand. <code>false</code> if the left operand
        *           is less than or equal to the right operand.
        */
       public static logical isGreaterThan(boolean op1, boolean op2)
       {
          return isGreaterThan(logical.of(op1), logical.of(op2));
       }

       /**
        * Determines if the left operand is greater than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than the
        *           right operand. <code>false</code> if the left operand
        *           is less than or equal to the right operand.
        *           <code>unknown</code> when the right operand is
        *           <code>unknown</code>.
        */
       public static logical isGreaterThan(String op1, BaseDataType op2)
       {
          return isGreaterThan(new character(op1), op2);
       }

       /**
        * Determines if the left operand is greater than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than the
        *           right operand. <code>false</code> if the left operand
        *           is less than or equal to the right operand.
        *           <code>unknown</code> when the left operand is
        *           <code>unknown</code>.
        */
       public static logical isGreaterThan(BaseDataType op1, String op2)
       {
          return isGreaterThan(op1, new character(op2));
       }

       /**
        * Determines if the left operand is greater than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than the
        *           right operand. <code>false</code> if the left operand
        *           is less than or equal to the right operand.
        */
       public static logical isGreaterThan(String op1, String op2)
       {
          // INLINED for efficiency...

          // DO NOT use String.compareToIgnoreCase() since this lowercases
          // and yields different results for >, <, >= and <= forms when
          // [ \ ^ _ ' characters are included in the operands
          int result = op1.toUpperCase().compareTo(op2.toUpperCase());

          return logical.of(result > 0);
       }

       /**
        * Determines if the left operand is greater than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than the
        *           right operand. <code>false</code> if the left operand
        *           is less than or equal to the right operand.
        *           <code>unknown</code> when the right operand is
        *           <code>unknown</code>.
        */
       public static logical isGreaterThan(long op1, BaseDataType op2)
       {
          return isGreaterThan(int64.of(op1), op2);
       }

       /**
        * Determines if the left operand is greater than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than the
        *           right operand. <code>false</code> if the left operand
        *           is less than or equal to the right operand.
        *           <code>unknown</code> when the left operand is
        *           <code>unknown</code>.
        */
       public static logical isGreaterThan(BaseDataType op1, long op2)
       {
          return isGreaterThan(op1, int64.of(op2));
       }

       /**
        * Determines if the left operand is greater than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than the
        *           right operand. <code>false</code> if the left operand
        *           is less than or equal to the right operand.
        */
       public static logical isGreaterThan(long op1, long op2)
       {
          // INLINED for efficiency...
          return logical.of(op1 > op2);
       }

       /**
        * Determines if the left operand is greater than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than the
        *           right operand. <code>false</code> if the left operand
        *           is less than or equal to the right operand.
        *           <code>unknown</code> when the right operand is
        *           <code>unknown</code>.
        */
       public static logical isGreaterThan(double op1, BaseDataType op2)
       {
          return isGreaterThan(new decimal(op1), op2);
       }

       /**
        * Determines if the left operand is greater than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than the
        *           right operand. <code>false</code> if the left operand
        *           is less than or equal to the right operand.
        *           <code>unknown</code> when the left operand is
        *           <code>unknown</code>.
        */
       public static logical isGreaterThan(BaseDataType op1, double op2)
       {
          return isGreaterThan(op1, new decimal(op2));
       }

       /**
        * Determines if the left operand is greater than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than the
        *           right operand. <code>false</code> if the left operand
        *           is less than or equal to the right operand.
        */
       public static logical isGreaterThan(double op1, double op2)
       {
          // also handles double > int and int > double cases
          return isGreaterThan(new decimal(op1), new decimal(op2));
       }

       /**
        * Determines if the left operand is greater than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than or
        *           equal to the right operand OR if both operands are
        *           <code>unknown</code>.  <code>false</code> if the left operand
        *           is less than the right operand OR when any one operand is
        *           <code>unknown</code> and the other is not.
        */
       public static boolean greaterThanOrEqual(BaseDataType op1, BaseDataType op2)
       {
          boolean u1 = op1.isUnknown();
          boolean u2 = op2.isUnknown();

          if (u1 && u2)
             return true;

          if (u1 || u2)
             return false;

          return (op1.compareTo(op2) >= 0);
       }

       /**
        * Determines if the left operand is greater than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than or
        *           equal to the right operand OR if both operands are
        *           <code>unknown</code>.  <code>false</code> if the left operand
        *           is less than the right operand.  <code>unknown</code>
        *           when any one operand is <code>unknown</code> and the other
        *           is not.
        */
       public static boolean _isGreaterThanOrEqual(BaseDataType op1, BaseDataType op2)
       {
          return greaterThanOrEqual(op1, op2);
       }

       /**
        * Determines if the left operand is greater than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is less than the right operand or when the left
        *           operand is <code>unknown</code>.
        */
       public static boolean _isGreaterThanOrEqual(BaseDataType op1, boolean op2)
       {
          return greaterThanOrEqual(op1, logical.of(op2));
       }

       /**
        * Determines if the left operand is greater than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is less than the right operand or when the right
        *           operand is <code>unknown</code>.
        */
       public static boolean _isGreaterThanOrEqual(boolean op1, BaseDataType op2)
       {
          return greaterThanOrEqual(logical.of(op1), op2);
       }

       /**
        * Determines if the left operand is greater than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is less than the right operand.
        */
       public static boolean _isGreaterThanOrEqual(boolean op1, boolean op2)
       {
          return greaterThanOrEqual(logical.of(op1), logical.of(op2));
       }

       /**
        * Determines if the left operand is greater than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is less than the right operand or when the left
        *           operand is <code>unknown</code>.
        */
       public static boolean _isGreaterThanOrEqual(BaseDataType op1, String op2)
       {
          return greaterThanOrEqual(op1, new character(op2));
       }

       /**
        * Determines if the left operand is greater than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is less than the right operand or when the right
        *           operand is <code>unknown</code>.
        */
       public static boolean _isGreaterThanOrEqual(String op1, BaseDataType op2)
       {
          return greaterThanOrEqual(new character(op1), op2);
       }

       /**
        * Determines if the left operand is greater than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is less than the right operand.
        */
       public static boolean _isGreaterThanOrEqual(String op1, String op2)
       {
          // INLINED for efficiency...

          // DO NOT use String.compareToIgnoreCase() since this lowercases
          // and yields different results for >, <, >= and <= forms when
          // [ \ ^ _ ' characters are included in the operands
          int result = op1.toUpperCase().compareTo(op2.toUpperCase());

          return (result >= 0);
       }

       /**
        * Determines if the left operand is greater than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is less than the right operand or when the left
        *           operand is <code>unknown</code>.
        */
       public static boolean _isGreaterThanOrEqual(BaseDataType op1, long op2)
       {
          return greaterThanOrEqual(op1, int64.of(op2));
       }

       /**
        * Determines if the left operand is greater than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is less than the right operand or when the right
        *           operand is <code>unknown</code>.
        */
       public static boolean _isGreaterThanOrEqual(long op1, BaseDataType op2)
       {
          return greaterThanOrEqual(new int64(op1), op2);
       }

       /**
        * Determines if the left operand is greater than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is less than the right operand.
        */
       public static boolean _isGreaterThanOrEqual(long op1, long op2)
       {
          // INLINED for efficiency...
          return (op1 >= op2);
       }

       /**
        * Determines if the left operand is greater than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is less than the right operand or when the left
        *           operand is <code>unknown</code>.
        */
       public static boolean _isGreaterThanOrEqual(BaseDataType op1, double op2)
       {
          return greaterThanOrEqual(op1, new decimal(op2));
       }

       /**
        * Determines if the left operand is greater than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is less than the right operand or when the right
        *           operand is <code>unknown</code>.
        */
       public static boolean _isGreaterThanOrEqual(double op1, BaseDataType op2)
       {
          return greaterThanOrEqual(new decimal(op1), op2);
       }

       /**
        * Determines if the left operand is greater than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is less than the right operand.
        */
       public static boolean _isGreaterThanOrEqual(double op1, double op2)
       {
          // also handles double >= int and int >= double cases
          return greaterThanOrEqual(new decimal(op1), new decimal(op2));
       }

       /**
        * Determines if the left operand is greater than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than or
        *           equal to the right operand OR if both operands are
        *           <code>unknown</code>.  <code>false</code> if the left operand
        *           is less than the right operand.  <code>unknown</code>
        *           when any one operand is <code>unknown</code> and the other
        *           is not.
        */
       public static logical isGreaterThanOrEqual(BaseDataType op1, BaseDataType op2)
       {
          boolean u1 = op1.isUnknown();
          boolean u2 = op2.isUnknown();

          if (u1 && u2)
             return logical.of(true);

          if (u1 || u2)
             return logical.UNKNOWN;

          return logical.of(op1.compareTo(op2) >= 0);
       }

       /**
        * Determines if the left operand is greater than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is less than the right operand.  <code>unknown</code>
        *           when the left operand is <code>unknown</code>.
        */
       public static logical isGreaterThanOrEqual(BaseDataType op1, boolean op2)
       {
          return isGreaterThanOrEqual(op1, logical.of(op2));
       }

       /**
        * Determines if the left operand is greater than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is less than the right operand.  <code>unknown</code>
        *           when the right operand is <code>unknown</code>.
        */
       public static logical isGreaterThanOrEqual(boolean op1, BaseDataType op2)
       {
          return isGreaterThanOrEqual(logical.of(op1), op2);
       }

       /**
        * Determines if the left operand is greater than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is less than the right operand.
        */
       public static logical isGreaterThanOrEqual(boolean op1, boolean op2)
       {
          return isGreaterThanOrEqual(logical.of(op1), logical.of(op2));
       }

       /**
        * Determines if the left operand is greater than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is less than the right operand.  <code>unknown</code>
        *           when the left operand is <code>unknown</code>.
        */
       public static logical isGreaterThanOrEqual(BaseDataType op1, String op2)
       {
          return isGreaterThanOrEqual(op1, new character(op2));
       }

       /**
        * Determines if the left operand is greater than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is less than the right operand.  <code>unknown</code>
        *           when the right operand is <code>unknown</code>.
        */
       public static logical isGreaterThanOrEqual(String op1, BaseDataType op2)
       {
          return isGreaterThanOrEqual(new character(op1), op2);
       }

       /**
        * Determines if the left operand is greater than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is less than the right operand.
        */
       public static logical isGreaterThanOrEqual(String op1, String op2)
       {
          // INLINED for efficiency...

          // DO NOT use String.compareToIgnoreCase() since this lowercases
          // and yields different results for >, <, >= and <= forms when
          // [ \ ^ _ ' characters are included in the operands
          int result = op1.toUpperCase().compareTo(op2.toUpperCase());

          return logical.of(result >= 0);
       }

       /**
        * Determines if the left operand is greater than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is less than the right operand.  <code>unknown</code>
        *           when the left operand is <code>unknown</code>.
        */
       public static logical isGreaterThanOrEqual(BaseDataType op1, long op2)
       {
          return isGreaterThanOrEqual(op1, new int64(op2));
       }

       /**
        * Determines if the left operand is greater than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is less than the right operand.  <code>unknown</code>
        *           when the right operand is <code>unknown</code>.
        */
       public static logical isGreaterThanOrEqual(long op1, BaseDataType op2)
       {
          return isGreaterThanOrEqual(new int64(op1), op2);
       }

       /**
        * Determines if the left operand is greater than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is less than the right operand.
        */
       public static logical isGreaterThanOrEqual(long op1, long op2)
       {
          // INLINED for efficiency...
          return logical.of(op1 >= op2);
       }

       /**
        * Determines if the left operand is greater than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is less than the right operand.  <code>unknown</code>
        *           when the left operand is <code>unknown</code>.
        */
       public static logical isGreaterThanOrEqual(BaseDataType op1, double op2)
       {
          return isGreaterThanOrEqual(op1, new decimal(op2));
       }

       /**
        * Determines if the left operand is greater than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is less than the right operand.  <code>unknown</code>
        *           when the right operand is <code>unknown</code>.
        */
       public static logical isGreaterThanOrEqual(double op1, BaseDataType op2)
       {
          return isGreaterThanOrEqual(new decimal(op1), op2);
       }

       /**
        * Determines if the left operand is greater than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is greater than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is less than the right operand.
        */
       public static logical isGreaterThanOrEqual(double op1, double op2)
       {
          // also handles double >= int and int >= double cases
          return isGreaterThanOrEqual(new decimal(op1), new decimal(op2));
       }

       /**
        * Determines if the left operand is less than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the first operand is less than the
        *           second operand.  <code>false</code> if the first operand
        *           is equal to or greater than the second operand OR when
        *           either or both operands are <code>unknown</code>.
        */
       public static boolean lessThan(BaseDataType op1, BaseDataType op2)
       {
          boolean u1 = op1.isUnknown();
          boolean u2 = op2.isUnknown();

          if (u1 || u2)
             return false;

          return (op1.compareTo(op2) < 0);
       }

       /**
        * Determines if the left operand is less than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than the
        *           right operand. <code>false</code> if the left operand
        *           is greater than or equal to the right operand OR if both
        *           operands are <code>unknown</code>.  <code>unknown</code>
        *           when any one operand is <code>unknown</code> and the other
        *           is not.
        */
       public static boolean _isLessThan(BaseDataType op1, BaseDataType op2)
       {
          return lessThan(op1, op2);
       }

       /**
        * Determines if the left operand is less than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than the
        *           right operand. <code>false</code> if the left operand
        *           is greater than or equal to the right operand or when the
        *           right operand is <code>unknown</code>.
        */
       public static boolean _isLessThan(boolean op1, BaseDataType op2)
       {
          return lessThan(logical.of(op1), op2);
       }

       /**
        * Determines if the left operand is less than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than the
        *           right operand. <code>false</code> if the left operand
        *           is greater than or equal to the right operand or when the
        *           left operand is <code>unknown</code>.
        */
       public static boolean _isLessThan(BaseDataType op1, boolean op2)
       {
          return lessThan(op1, logical.of(op2));
       }

       /**
        * Determines if the left operand is less than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than the
        *           right operand. <code>false</code> if the left operand
        *           is greater than or equal to the right operand.
        */
       public static boolean _isLessThan(boolean op1, boolean op2)
       {
          return lessThan(logical.of(op1), logical.of(op2));
       }

       /**
        * Determines if the left operand is less than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than the
        *           right operand. <code>false</code> if the left operand
        *           is greater than or equal to the right operand or when the
        *           right operand is <code>unknown</code>.
        */
       public static boolean _isLessThan(String op1, BaseDataType op2)
       {
          return lessThan(new character(op1), op2);
       }

       /**
        * Determines if the left operand is less than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than the
        *           right operand. <code>false</code> if the left operand
        *           is greater than or equal to the right operand or when the
        *           left operand is <code>unknown</code>.
        */
       public static boolean _isLessThan(BaseDataType op1, String op2)
       {
          return lessThan(op1, new character(op2));
       }

       /**
        * Determines if the left operand is less than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than the
        *           right operand. <code>false</code> if the left operand
        *           is greater than or equal to the right operand.
        */
       public static boolean _isLessThan(String op1, String op2)
       {
          // INLINED for efficiency...

          // DO NOT use String.compareToIgnoreCase() since this lowercases
          // and yields different results for >, <, >= and <= forms when
          // [ \ ^ _ ' characters are included in the operands
          int result = op1.toUpperCase().compareTo(op2.toUpperCase());

          return (result < 0);
       }

       /**
        * Determines if the left operand is less than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than the
        *           right operand. <code>false</code> if the left operand
        *           is greater than or equal to the right operand or when the
        *           right operand is <code>unknown</code>.
        */
       public static boolean _isLessThan(long op1, BaseDataType op2)
       {
          return lessThan(int64.of(op1), op2);
       }

       /**
        * Determines if the left operand is less than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than the
        *           right operand. <code>false</code> if the left operand
        *           is greater than or equal to the right operand or when the
        *           left operand is <code>unknown</code>.
        */
       public static boolean _isLessThan(BaseDataType op1, long op2)
       {
          return lessThan(op1, int64.of(op2));
       }

       /**
        * Determines if the left operand is less than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than the
        *           right operand. <code>false</code> if the left operand
        *           is greater than or equal to the right operand.
        */
       public static boolean _isLessThan(long op1, long op2)
       {
          // INLINED for efficiency...
          return (op1 < op2);
       }

       /**
        * Determines if the left operand is less than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than the
        *           right operand. <code>false</code> if the left operand
        *           is greater than or equal to the right operand or when the
        *           right operand is <code>unknown</code>.
        */
       public static boolean _isLessThan(double op1, BaseDataType op2)
       {
          return lessThan(new decimal(op1), op2);
       }

       /**
        * Determines if the left operand is less than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than the
        *           right operand. <code>false</code> if the left operand
        *           is greater than or equal to the right operand or when the
        *           left operand is <code>unknown</code>.
        */
       public static boolean _isLessThan(BaseDataType op1, double op2)
       {
          return lessThan(op1, new decimal(op2));
       }

       /**
        * Determines if the left operand is less than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than the
        *           right operand. <code>false</code> if the left operand
        *           is greater than or equal to the right operand.
        */
       public static boolean _isLessThan(double op1, double op2)
       {
          // also handles the double < int and int < double cases
          return lessThan(new decimal(op1), new decimal(op2));
       }

       /**
        * Determines if the left operand is less than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than the
        *           right operand. <code>false</code> if the left operand
        *           is greater than or equal to the right operand OR if both
        *           operands are <code>unknown</code>.  <code>unknown</code>
        *           when any one operand is <code>unknown</code> and the other
        *           is not.
        */
       public static logical isLessThan(BaseDataType op1, BaseDataType op2)
       {
          boolean u1 = op1.isUnknown();
          boolean u2 = op2.isUnknown();

          if (u1 && u2)
             return logical.of(false);

          if (u1 || u2)
             return logical.UNKNOWN;

          return logical.of(op1.compareTo(op2) < 0);
       }

       /**
        * Determines if the left operand is less than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than the
        *           right operand. <code>false</code> if the left operand
        *           is greater than or equal to the right operand.
        *           <code>unknown</code> when the right operand is
        *           <code>unknown</code>.
        */
       public static logical isLessThan(boolean op1, BaseDataType op2)
       {
          return isLessThan(logical.of(op1), op2);
       }

       /**
        * Determines if the left operand is less than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than the
        *           right operand. <code>false</code> if the left operand
        *           is greater than or equal to the right operand.
        *           <code>unknown</code> when the left operand is
        *           <code>unknown</code>.
        */
       public static logical isLessThan(BaseDataType op1, boolean op2)
       {
          return isLessThan(op1, logical.of(op2));
       }

       /**
        * Determines if the left operand is less than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than the
        *           right operand. <code>false</code> if the left operand
        *           is greater than or equal to the right operand.
        */
       public static logical isLessThan(boolean op1, boolean op2)
       {
          return isLessThan(logical.of(op1), logical.of(op2));
       }

       /**
        * Determines if the left operand is less than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than the
        *           right operand. <code>false</code> if the left operand
        *           is greater than or equal to the right operand.
        *           <code>unknown</code> when the right operand is
        *           <code>unknown</code>.
        */
       public static logical isLessThan(String op1, BaseDataType op2)
       {
          return isLessThan(new character(op1), op2);
       }

       /**
        * Determines if the left operand is less than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than the
        *           right operand. <code>false</code> if the left operand
        *           is greater than or equal to the right operand.
        *           <code>unknown</code> when the left operand is
        *           <code>unknown</code>.
        */
       public static logical isLessThan(BaseDataType op1, String op2)
       {
          return isLessThan(op1, new character(op2));
       }

       /**
        * Determines if the left operand is less than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than the
        *           right operand. <code>false</code> if the left operand
        *           is greater than or equal to the right operand.
        */
       public static logical isLessThan(String op1, String op2)
       {
          // INLINED for efficiency...

          // DO NOT use String.compareToIgnoreCase() since this lowercases
          // and yields different results for >, <, >= and <= forms when
          // [ \ ^ _ ' characters are included in the operands
          int result = op1.toUpperCase().compareTo(op2.toUpperCase());

          return logical.of(result < 0);
       }

       /**
        * Determines if the left operand is less than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than the
        *           right operand. <code>false</code> if the left operand
        *           is greater than or equal to the right operand.
        *           <code>unknown</code> when the right operand is
        *           <code>unknown</code>.
        */
       public static logical isLessThan(long op1, BaseDataType op2)
       {
          return isLessThan(new int64(op1), op2);
       }

       /**
        * Determines if the left operand is less than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than the
        *           right operand. <code>false</code> if the left operand
        *           is greater than or equal to the right operand.
        *           <code>unknown</code> when the left operand is
        *           <code>unknown</code>.
        */
       public static logical isLessThan(BaseDataType op1, long op2)
       {
          return isLessThan(op1, int64.of(op2));
       }

       /**
        * Determines if the left operand is less than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than the
        *           right operand. <code>false</code> if the left operand
        *           is greater than or equal to the right operand.
        */
       public static logical isLessThan(long op1, long op2)
       {
          // INLINED for efficiency...
          return logical.of(op1 < op2);
       }

       /**
        * Determines if the left operand is less than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than the
        *           right operand. <code>false</code> if the left operand
        *           is greater than or equal to the right operand.
        *           <code>unknown</code> when the right operand is
        *           <code>unknown</code>.
        */
       public static logical isLessThan(double op1, BaseDataType op2)
       {
          return isLessThan(new decimal(op1), op2);
       }

       /**
        * Determines if the left operand is less than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than the
        *           right operand. <code>false</code> if the left operand
        *           is greater than or equal to the right operand.
        *           <code>unknown</code> when the left operand is
        *           <code>unknown</code>.
        */
       public static logical isLessThan(BaseDataType op1, double op2)
       {
          return isLessThan(op1, new decimal(op2));
       }

       /**
        * Determines if the left operand is less than the right operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than the
        *           right operand. <code>false</code> if the left operand
        *           is greater than or equal to the right operand.
        */
       public static logical isLessThan(double op1, double op2)
       {
          // also handles the double < int and int < double cases
          return isLessThan(new decimal(op1), new decimal(op2));
       }

       /**
        * Determines if the left operand is less than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than or
        *           equal to the right operand OR if both operands are
        *           <code>unknown</code>.  <code>false</code> if the left operand
        *           is greater than the right operand OR when any one operand is
        *           <code>unknown</code> and the other is not.
        */
       public static boolean lessThanOrEqual(BaseDataType op1, BaseDataType op2)
       {
          boolean u1 = op1.isUnknown();
          boolean u2 = op2.isUnknown();

          if (u1 && u2)
             return true;

          if (u1 || u2)
             return false;

          return (op1.compareTo(op2) <= 0);
       }

       /**
        * Determines if the left operand is less than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than or
        *           equal to the right operand OR if both operands are
        *           <code>unknown</code>.  <code>false</code> if the left operand
        *           is greater than the right operand or when one (but not both)
        *           operands are <code>unknown</code>.
        */
       public static boolean _isLessThanOrEqual(BaseDataType op1, BaseDataType op2)
       {
          return lessThanOrEqual(op1, op2);
       }

       /**
        * Determines if the left operand is less than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is greater than the right operand or when the right
        *           operand is <code>unknown</code>.
        */
       public static boolean _isLessThanOrEqual(boolean op1, BaseDataType op2)
       {
          return lessThanOrEqual(logical.of(op1), op2);
       }

       /**
        * Determines if the left operand is less than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is greater than the right operand or when the left
        *           operand is <code>unknown</code>.
        */
       public static boolean _isLessThanOrEqual(BaseDataType op1, boolean op2)
       {
          return lessThanOrEqual(op1, logical.of(op2));
       }

       /**
        * Determines if the left operand is less than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is greater than the right operand.
        */
       public static boolean _isLessThanOrEqual(boolean op1, boolean op2)
       {
          return lessThanOrEqual(logical.of(op1), logical.of(op2));
       }

       /**
        * Determines if the left operand is less than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is greater than the right operand or when the right
        *           operand is <code>unknown</code>.
        */
       public static boolean _isLessThanOrEqual(String op1, BaseDataType op2)
       {
          return lessThanOrEqual(new character(op1), op2);
       }

       /**
        * Determines if the left operand is less than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is greater than the right operand or when the left
        *           operand is <code>unknown</code>.
        */
       public static boolean _isLessThanOrEqual(BaseDataType op1, String op2)
       {
          return lessThanOrEqual(op1, new character(op2));
       }

       /**
        * Determines if the left operand is less than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is greater than the right operand.
        */
       public static boolean _isLessThanOrEqual(String op1, String op2)
       {
          // INLINED for efficiency...

          // DO NOT use String.compareToIgnoreCase() since this lowercases
          // and yields different results for >, <, >= and <= forms when
          // [ \ ^ _ ' characters are included in the operands
          int result = op1.toUpperCase().compareTo(op2.toUpperCase());

          return (result <= 0);
       }

       /**
        * Determines if the left operand is less than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is greater than the right operand or when the right
        *           operand is <code>unknown</code>.
        */
       public static boolean _isLessThanOrEqual(long op1, BaseDataType op2)
       {
          return lessThanOrEqual(new int64(op1), op2);
       }

       /**
        * Determines if the left operand is less than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is greater than the right operand or when the left
        *           operand is <code>unknown</code>.
        */
       public static boolean _isLessThanOrEqual(BaseDataType op1, long op2)
       {
          return lessThanOrEqual(op1, int64.of(op2));
       }

       /**
        * Determines if the left operand is less than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is greater than the right operand.
        */
       public static boolean _isLessThanOrEqual(long op1, long op2)
       {
          // INLINED for efficiency...
          return (op1 <= op2);
       }

       /**
        * Determines if the left operand is less than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is greater than the right operand or when the right
        *           operand is <code>unknown</code>.
        */
       public static boolean _isLessThanOrEqual(double op1, BaseDataType op2)
       {
          return lessThanOrEqual(new decimal(op1), op2);
       }

       /**
        * Determines if the left operand is less than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is greater than the right operand or when the left
        *           operand is <code>unknown</code>.
        */
       public static boolean _isLessThanOrEqual(BaseDataType op1, double op2)
       {
          return lessThanOrEqual(op1, new decimal(op2));
       }

       /**
        * Determines if the left operand is less than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is greater than the right operand.
        */
       public static boolean _isLessThanOrEqual(double op1, double op2)
       {
          // also handles double <= int and int <= double
          return lessThanOrEqual(new decimal(op1), new decimal(op2));
       }

       /**
        * Determines if the left operand is less than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than or
        *           equal to the right operand OR if both operands are
        *           <code>unknown</code>.  <code>false</code> if the left operand
        *           is greater than the right operand.  <code>unknown</code>
        *           when any one operand is <code>unknown</code> and the other
        *           is not.
        */
       public static logical isLessThanOrEqual(BaseDataType op1, BaseDataType op2)
       {
          boolean u1 = op1.isUnknown();
          boolean u2 = op2.isUnknown();

          if (u1 && u2)
             return logical.of(true);

          if (u1 || u2)
             return logical.UNKNOWN;

          return logical.of(op1.compareTo(op2) <= 0);
       }

       /**
        * Determines if the left operand is less than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is greater than the right operand.
        *           <code>unknown</code> when the right operand is
        *           <code>unknown</code>.
        */
       public static logical isLessThanOrEqual(boolean op1, BaseDataType op2)
       {
          return isLessThanOrEqual(logical.of(op1), op2);
       }

       /**
        * Determines if the left operand is less than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is greater than the right operand.
        *           <code>unknown</code> when the left operand is
        *           <code>unknown</code>.
        */
       public static logical isLessThanOrEqual(BaseDataType op1, boolean op2)
       {
          return isLessThanOrEqual(op1, logical.of(op2));
       }

       /**
        * Determines if the left operand is less than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is greater than the right operand.
        */
       public static logical isLessThanOrEqual(boolean op1, boolean op2)
       {
          return isLessThanOrEqual(logical.of(op1), logical.of(op2));
       }

       /**
        * Determines if the left operand is less than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is greater than the right operand.
        *           <code>unknown</code> when the right operand is
        *           <code>unknown</code>.
        */
       public static logical isLessThanOrEqual(String op1, BaseDataType op2)
       {
          return isLessThanOrEqual(new character(op1), op2);
       }

       /**
        * Determines if the left operand is less than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is greater than the right operand.
        *           <code>unknown</code> when the left operand is
        *           <code>unknown</code>.
        */
       public static logical isLessThanOrEqual(BaseDataType op1, String op2)
       {
          return isLessThanOrEqual(op1, new character(op2));
       }

       /**
        * Determines if the left operand is less than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is greater than the right operand.
        */
       public static logical isLessThanOrEqual(String op1, String op2)
       {
          // INLINED for efficiency...

          // DO NOT use String.compareToIgnoreCase() since this lowercases
          // and yields different results for >, <, >= and <= forms when
          // [ \ ^ _ ' characters are included in the operands
          int result = op1.toUpperCase().compareTo(op2.toUpperCase());

          return logical.of(result <= 0);
       }

       /**
        * Determines if the left operand is less than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is greater than the right operand.
        *           <code>unknown</code> when the right operand is
        *           <code>unknown</code>.
        */
       public static logical isLessThanOrEqual(long op1, BaseDataType op2)
       {
          return isLessThanOrEqual(int64.of(op1), op2);
       }

       /**
        * Determines if the left operand is less than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is greater than the right operand.
        *           <code>unknown</code> when the left operand is
        *           <code>unknown</code>.
        */
       public static logical isLessThanOrEqual(BaseDataType op1, long op2)
       {
          return isLessThanOrEqual(op1, int64.of(op2));
       }

       /**
        * Determines if the left operand is less than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is greater than the right operand.
        */
       public static logical isLessThanOrEqual(long op1, long op2)
       {
          // INLINED for efficiency...
          return logical.of(op1 <= op2);
       }

       /**
        * Determines if the left operand is less than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is greater than the right operand.
        *           <code>unknown</code> when the right operand is
        *           <code>unknown</code>.
        */
       public static logical isLessThanOrEqual(double op1, BaseDataType op2)
       {
          return isLessThanOrEqual(new decimal(op1), op2);
       }

       /**
        * Determines if the left operand is less than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is greater than the right operand.
        *           <code>unknown</code> when the left operand is
        *           <code>unknown</code>.
        */
       public static logical isLessThanOrEqual(BaseDataType op1, double op2)
       {
          return isLessThanOrEqual(op1, new decimal(op2));
       }

       /**
        * Determines if the left operand is less than or equal to the right
        * operand.
        *
        * @param    op1
        *           The left operand.
        * @param    op2
        *           The right operand.
        *
        * @return   <code>true</code> if the left operand is less than or
        *           equal to the right operand.  <code>false</code> if the left
        *           operand is greater than the right operand.
        */
       public static logical isLessThanOrEqual(double op1, double op2)
       {
          // also handles double <= int and int <= double
          return isLessThanOrEqual(new decimal(op1), new decimal(op2));
       }
    }