Helper method for testing equals on two primitive or boxable objects.
yuck: factor this out into Primitive.java
965864
private boolean primitiveEquals(
        Object switchVal, Object targetVal,
        CallStack callstack, SimpleNode switchExp  )
        throws EvalError
    {
        if (targetVal == Primitive.VOID)
            return false;
        if ( switchVal instanceof Primitive || targetVal instanceof Primitive )
            try {
                // binaryOperation can return Primitive or wrapper type
                Object result = Operators.binaryOperation(
                    switchVal, targetVal, ParserConstants.EQ );
                result = Primitive.unwrap( result );
                return result.equals( Boolean.TRUE );
            } catch ( UtilEvalError e ) {
                throw e.toEvalError(
                    "Switch value: "+switchExp.getText()+": ",
                    this, callstack );
            }
        else
            return switchVal.equals( targetVal );
    }
8059
private int compare(Object k1, Object k2) {
        return (mComparator==null ? ((Comparable)k1).compareTo(k2)
                : mComparator.compare(k1, k2));
    }
1103792
public static boolean equalsOne(Object _obj, Object... _arrObj) {
       if (_obj == null || _arrObj == null) {
           return false;
       }
       for (Object o : _arrObj) {
           if (o != null && _obj.equals(o)) {
               return true;
           }
       }
       return false;
   }
500054
def simple_equality(cls, first, second, msg=None):
        
        if not first==second:
            standardMsg = '%s != %s' % (safe_repr(first), safe_repr(second))
            raise cls.failureException(msg or standardMsg)
1109663
private static boolean arrayEquals(Object o1, Object o2) {
        if (o1 instanceof Object[] && o2 instanceof Object[]) {
            return Arrays.equals((Object[]) o1, (Object[]) o2);
        }
        if (o1 instanceof boolean[] && o2 instanceof boolean[]) {
            return Arrays.equals((boolean[]) o1, (boolean[]) o2);
        }
        if (o1 instanceof byte[] && o2 instanceof byte[]) {
            return Arrays.equals((byte[]) o1, (byte[]) o2);
        }
        if (o1 instanceof char[] && o2 instanceof char[]) {
            return Arrays.equals((char[]) o1, (char[]) o2);
        }
        if (o1 instanceof double[] && o2 instanceof double[]) {
            return Arrays.equals((double[]) o1, (double[]) o2);
        }
        if (o1 instanceof float[] && o2 instanceof float[]) {
            return Arrays.equals((float[]) o1, (float[]) o2);
        }
        if (o1 instanceof int[] && o2 instanceof int[]) {
            return Arrays.equals((int[]) o1, (int[]) o2);
        }
        if (o1 instanceof long[] && o2 instanceof long[]) {
            return Arrays.equals((long[]) o1, (long[]) o2);
        }
        if (o1 instanceof short[] && o2 instanceof short[]) {
            return Arrays.equals((short[]) o1, (short[]) o2);
        }
        return false;
    }

    /**
     * Return as hash code for the given object; typically the value of
     * {@code Object#hashCode()}}. If the object is an array,
     * this method will delegate to any of the {@code nullSafeHashCode}
     * methods for arrays in this class. If the object is {@code null},
     * this method returns 0.
     *
     * @param obj the given object
     * @return a hash code value
     */
    public static int nullSafeHashCode(Object obj) {
        if (obj == null) {
            return 0;
        }
        if (obj.getClass().isArray()) {
            if (obj instanceof Object[]) {
                return nullSafeHashCode((Object[]) obj);
            }
            if (obj instanceof boolean[]) {
                return nullSafeHashCode((boolean[]) obj);
            }
            if (obj instanceof byte[]) {
                return nullSafeHashCode((byte[]) obj);
            }
            if (obj instanceof char[]) {
                return nullSafeHashCode((char[]) obj);
            }
            if (obj instanceof double[]) {
                return nullSafeHashCode((double[]) obj);
            }
            if (obj instanceof float[]) {
                return nullSafeHashCode((float[]) obj);
            }
            if (obj instanceof int[]) {
                return nullSafeHashCode((int[]) obj);
            }
            if (obj instanceof long[]) {
                return nullSafeHashCode((long[]) obj);
            }
            if (obj instanceof short[]) {
                return nullSafeHashCode((short[]) obj);
            }
        }
        return obj.hashCode();
    }

    /**
     * Return a hash code based on the contents of the specified array.
     * If {@code array} is {@code null}, this method returns 0.
     *
     * @param array the specified array
     * @return a hash code value
     */
    public static int nullSafeHashCode(Object[] array) {
        if (array == null) {
            return 0;
        }
        int hash = INITIAL_HASH;
        for (Object element : array) {
            hash = MULTIPLIER * hash + nullSafeHashCode(element);
        }
        return hash;
    }

    /**
     * Return a hash code based on the contents of the specified array.
     * If {@code array} is {@code null}, this method returns 0.
     *
     * @param array the specified array
     * @return a hash code value
     */
    public static int nullSafeHashCode(boolean[] array) {
        if (array == null) {
            return 0;
        }
        int hash = INITIAL_HASH;
        for (boolean element : array) {
            hash = MULTIPLIER * hash + Boolean.hashCode(element);
        }
        return hash;
    }

    /**
     * Return a hash code based on the contents of the specified array.
     * If {@code array} is {@code null}, this method returns 0.
     *
     * @param array the specified array
     * @return a hash code value
     */
    public static int nullSafeHashCode(byte[] array) {
        if (array == null) {
            return 0;
        }
        int hash = INITIAL_HASH;
        for (byte element : array) {
            hash = MULTIPLIER * hash + element;
        }
        return hash;
    }

    /**
     * Return a hash code based on the contents of the specified array.
     * If {@code array} is {@code null}, this method returns 0.
     *
     * @param array the specified array
     * @return a hash code value
     */
    public static int nullSafeHashCode(char[] array) {
        if (array == null) {
            return 0;
        }
        int hash = INITIAL_HASH;
        for (char element : array) {
            hash = MULTIPLIER * hash + element;
        }
        return hash;
    }

    /**
     * Return a hash code based on the contents of the specified array.
     * If {@code array} is {@code null}, this method returns 0.
     *
     * @param array the specified array
     * @return a hash code value
     */
    public static int nullSafeHashCode(double[] array) {
        if (array == null) {
            return 0;
        }
        int hash = INITIAL_HASH;
        for (double element : array) {
            hash = MULTIPLIER * hash + Double.hashCode(element);
        }
        return hash;
    }

    /**
     * Return a hash code based on the contents of the specified array.
     * If {@code array} is {@code null}, this method returns 0.
     *
     * @param array the specified array
     * @return a hash code value
     */
    public static int nullSafeHashCode(float[] array) {
        if (array == null) {
            return 0;
        }
        int hash = INITIAL_HASH;
        for (float element : array) {
            hash = MULTIPLIER * hash + Float.hashCode(element);
        }
        return hash;
    }

    /**
     * Return a hash code based on the contents of the specified array.
     * If {@code array} is {@code null}, this method returns 0.
     *
     * @param array the specified array
     * @return a hash code value
     */
    public static int nullSafeHashCode(int[] array) {
        if (array == null) {
            return 0;
        }
        int hash = INITIAL_HASH;
        for (int element : array) {
            hash = MULTIPLIER * hash + element;
        }
        return hash;
    }

    /**
     * Return a hash code based on the contents of the specified array.
     * If {@code array} is {@code null}, this method returns 0.
     *
     * @param array the specified array
     * @return a hash code value
     */
    public static int nullSafeHashCode(long[] array) {
        if (array == null) {
            return 0;
        }
        int hash = INITIAL_HASH;
        for (long element : array) {
            hash = MULTIPLIER * hash + Long.hashCode(element);
        }
        return hash;
    }

    /**
     * Return a hash code based on the contents of the specified array.
     * If {@code array} is {@code null}, this method returns 0.
     *
     * @param array the specified array
     * @return a hash code value
     */
    public static int nullSafeHashCode(short[] array) {
        if (array == null) {
            return 0;
        }
        int hash = INITIAL_HASH;
        for (short element : array) {
            hash = MULTIPLIER * hash + element;
        }
        return hash;
    }

}
787440
public static boolean deepEquals(Object a, Object b) {
        if (a == null || b == null) {
            return a == b;
        } else if (a instanceof Object[] && b instanceof Object[]) {
            return Arrays.deepEquals((Object[]) a, (Object[]) b);
        } else if (a instanceof boolean[] && b instanceof boolean[]) {
            return Arrays.equals((boolean[]) a, (boolean[]) b);
        } else if (a instanceof byte[] && b instanceof byte[]) {
            return Arrays.equals((byte[]) a, (byte[]) b);
        } else if (a instanceof char[] && b instanceof char[]) {
            return Arrays.equals((char[]) a, (char[]) b);
        } else if (a instanceof double[] && b instanceof double[]) {
            return Arrays.equals((double[]) a, (double[]) b);
        } else if (a instanceof float[] && b instanceof float[]) {
            return Arrays.equals((float[]) a, (float[]) b);
        } else if (a instanceof int[] && b instanceof int[]) {
            return Arrays.equals((int[]) a, (int[]) b);
        } else if (a instanceof long[] && b instanceof long[]) {
            return Arrays.equals((long[]) a, (long[]) b);
        } else if (a instanceof short[] && b instanceof short[]) {
            return Arrays.equals((short[]) a, (short[]) b);
        }
        return a.equals(b);
    }

    /**
     * NULL safe reference unwrap
     */
    public static <T> T unwrap(Reference<T> reference) {
        return reference == null ? null : reference.get();
    }

    /**
     * NULL safe reference unwrap
     */
    public static <T> T unwrap(AtomicReference<T> reference) {
        return reference == null ? null : reference.get();
    }

    public static boolean isNull(Object object) {
        return object == null;
    }

    public static boolean nonNull(Object object) {
        return object != null;
    }

    /**
     * Null-safe equivalent of {@code a.equals(b)}.
     */
    public static boolean equal(Object a, Object b) {
        return (a == null) ? (b == null) : a.equals(b);
    }

    /**
     * Null-safe equivalent of {@code !a.equals(b)}.
     */
    public static boolean notEqual(Object a, Object b) {
        return !equal(a, b);
    }

    /**
     * Convenience wrapper for {@link Arrays#hashCode}, adding varargs.
     * This can be used to compute a hash code for an object's fields as follows:
     * {@code Objects.hash(a, b, c)}.
     */
    public static int hash(Object... values) {
        return Arrays.hashCode(values);
    }

    /**
     * Convenience wrapper for {@link Arrays#hashCode}, adding varargs.
     * This can be used to compute a hash code for an object's fields as follows:
     * {@code Objects.hash(a, b, c)}.
     */
    public static int hash(List<?> values) {
        if (values == null)
            return 0;

        int result = 1;

        for (Object element : values)
            result = 31 * result + (element == null ? 0 : element.hashCode());

        return result;
    }

    /**
     * Convenience wrapper for {@link Arrays#hashCode}, adding varargs.
     * This can be used to compute a hash code for an object's fields as follows:
     * {@code Objects.hash(a, b, c)}.
     */
    public static int absHash(Object... values) {
        return abs(Arrays.hashCode(values));
    }

    /**
     * Returns 0 for null or {@code o.hashCode()}.
     */
    public static int hashCode(Object o) {
        return (o == null) ? 0 : o.hashCode();
    }

    /**
     * @return secondary hash from object's hash
     */
    public static int secondaryHash(Object key) {
        return secondaryHash(key.hashCode());
    }

    /**
     * @return secondary hash from identity hash
     */
    public static int secondaryIdentityHash(Object key) {
        return secondaryHash(System.identityHashCode(key));
    }

    /**
     * @return secondary hash from hash
     */
    private static int secondaryHash(int h) {
        // Spread bits to regularize both segment and index locations,
        // using variant of single-word Wang/Jenkins hash.
        h += (h << 15) ^ 0xffffcd7d;
        h ^= (h >>> 10);
        h += (h << 3);
        h ^= (h >>> 6);
        h += (h << 2) + (h << 14);
        return h ^ (h >>> 16);
    }

    /**
     * Returns {@code o} if non-null, or throws {@code NullPointerException}.
     */
    public static <T> T requireNonNull(T o) {
        if (o == null) {
            throw new NullPointerException();
        }
        return o;
    }

    /**
     * Returns {@code o} if non-null, or throws {@code NullPointerException}
     * with the given detail message.
     */
    public static <T> T requireNonNull(T o, String message) {
        if (o == null) {
            throw new NullPointerException(message);
        }
        return o;
    }

    /**
     * Returns true if the string is null or 0-length.
     *
     * @param str the string to be examined
     * @return true if str is null or zero length
     */
    public static boolean isEmpty(CharSequence str) {
        if (str == null || str.length() == 0)
            return true;
        else
            return false;
    }

    /**
     * Returns false if the string is null or 0-length.
     *
     * @param str the string to be examined
     * @return false if str is null or zero length
     */
    public static boolean isNotEmpty(CharSequence str) {
        if (str == null || str.length() == 0)
            return false;
        else
            return true;
    }

    /**
     * Returns NULL for null or {@code o.toString()}.
     */
    public static String toString(Object o) {
        return (o == null) ? null : o.toString();
    }

    /**
     * Returns NULL for null or {@code o.toString()}.
     */
    public static List<String> toString(Object... o) {
        List<String> strings = new ArrayList<>();
        for (Object item : o) {
            strings.add(toString(item));
        }
        return strings;
    }

    /**
     * Returns NULL for null or {@code o.toString()}.
     */
    public static List<String> toString(Collection o) {
        List<String> strings = new ArrayList<>();
        for (Object item : o) {
            strings.add(toString(item));
        }
        return strings;
    }

    /**
     * Returns "null" for null or {@code o.toString()}.
     */
    public static String string(Object o) {
        return (o == null) ? "null" : o.toString();
    }

    /**
     * Returns "null" for null or {@code o.toString()}.
     */
    public static List<String> string(Object... o) {
        List<String> strings = new ArrayList<>();
        for (Object item : o) {
            strings.add(string(item));
        }
        return strings;
    }

    /**
     * Returns "null" for null or {@code o.toString()}.
     */
    public static List<String> string(Collection o) {
        List<String> strings = new ArrayList<>();
        for (Object item : o) {
            strings.add(toString(item));
        }
        return strings;
    }

    /**
     * Returns {@code nullString} for null or {@code o.toString()}.
     */
    public static String string(Object o, String nullString) {
        return (o == null) ? nullString : o.toString();
    }

    /**
     * NULL safe startsWith()
     */
    public static boolean startsWith(String string, String prefix) {
        return isEmpty(string) && isEmpty(prefix) || string != null && string.startsWith(prefix);
    }

    /**
     * NULL safe contains()
     */
    public static boolean contains(String string, String value) {
        return safe(string).contains(value);
    }

    /**
     * NULL safe replace()
     */
    public static String replace(String string, CharSequence target, CharSequence replacement) {
        return string == null ? null : string.replace(target, replacement);
    }

    /**
     * NULL safe replaceFirst()
     */
    public static String replaceFirst(String string, String regex, String replacement) {
        return string == null ? null : string.replaceFirst(regex, replacement);
    }

    /**
     * NULL safe replaceAll()
     */
    public static String replaceAll(String string, String regex, String replacement) {
        return string == null ? null : string.replaceAll(regex, replacement);
    }

    /**
     * NULL safe trim()
     */
    public static String trim(String string) {
        return string == null ? null : string.trim();
    }

    /**
     * NULL safe trim()
     */
    public static boolean isTrimmedEmpty(String string) {
        return string == null || string.trim().isEmpty();
    }

    /**
     * Returns a string containing the tokens joined.
     *
     * @param delimiter object to insert between {@code tokens}
     * @param tokens    an array objects to be joined
     */
    public static <T> List<T> insertBetween(T delimiter, List<T> tokens) {
        List<T> sb = new ArrayList<>();
        boolean firstTime = true;
        for (T token : tokens) {
            if (firstTime) {
                firstTime = false;
            } else {
                sb.add(delimiter);
            }
            sb.add(token);
        }
        return sb;
    }

    /**
     * Returns a string containing the tokens joined.
     *
     * @param list an array objects to be joined. Strings will be formed from
     *             the objects by calling object.toString().
     */
    public static CharSequence join(Object... list) {
        return join("", list);
    }

    /**
     * Returns a string containing the tokens joined by delimiters.
     *
     * @param tokens an array objects to be joined. Strings will be formed from
     *               the objects by calling object.toString().
     */
    public static String join(CharSequence delimiter, Object... tokens) {
        StringBuilder sb = new StringBuilder();
        boolean firstTime = true;
        for (Object token : tokens) {
            if (firstTime) {
                firstTime = false;
            } else {
                sb.append(delimiter);
            }
            sb.append(token);
        }
        return sb.toString();
    }

    /**
     * Returns a string containing the tokens joined by delimiters.
     *
     * @param tokens an array objects to be joined. Strings will be formed from
     *               the objects by calling object.toString() NULL items won't be added.
     */
    public static String joinNotNull(CharSequence delimiter, Object... tokens) {
        StringBuilder sb = new StringBuilder();
        boolean firstTime = true;
        for (Object token : tokens) {
            if (token != null) {
                if (firstTime) {
                    firstTime = false;
                } else {
                    sb.append(delimiter);
                }
                sb.append(token);
            }
        }
        return sb.toString();
    }

    /**
     * Returns a string containing the tokens joined by delimiters.
     *
     * @param tokens an array objects to be joined. Strings will be formed from
     *               the objects by calling object.toString() EMPTY items won't be added.
     */
    public static String joinNotEmpty(CharSequence delimiter, Object... tokens) {
        StringBuilder sb = new StringBuilder();
        boolean firstTime = true;
        for (Object token : tokens) {
            if (!isEmpty(toString(token))) {
                if (firstTime) {
                    firstTime = false;
                } else {
                    sb.append(delimiter);
                }
                sb.append(token);
            }
        }
        return sb.toString();
    }


    /**
     * Returns a string containing the tokens joined.
     *
     * @param tokens an array objects to be joined. Strings will be formed from
     *               the objects by calling object.toString().
     */
    public static CharSequence join(Iterable tokens) {
        return join("", tokens);
    }

    /**
     * Returns a string containing the tokens joined by delimiters.
     *
     * @param tokens an array objects to be joined. Strings will be formed from
     *               the objects by calling object.toString().
     */
    public static String join(CharSequence delimiter, Iterable tokens) {
        StringBuilder sb = new StringBuilder();
        boolean firstTime = true;
        for (Object token : tokens) {
            if (firstTime) {
                firstTime = false;
            } else {
                sb.append(delimiter);
            }
            sb.append(token);
        }
        return sb.toString();
    }

    /**
     * Returns a string containing the tokens joined by delimiters.
     *
     * @param tokens an array objects to be joined. Strings will be formed from
     *               the objects by calling object.toString() NULL items won't be added.
     */
    public static String joinNotNull(CharSequence delimiter, Iterable tokens) {
        StringBuilder sb = new StringBuilder();
        boolean firstTime = true;
        for (Object token : tokens) {
            if (token != null) {
                if (firstTime) {
                    firstTime = false;
                } else {
                    sb.append(delimiter);
                }
                sb.append(token);
            }
        }
        return sb.toString();
    }

    /**
     * Returns a string containing the tokens joined by delimiters.
     *
     * @param tokens an array objects to be joined. Strings will be formed from
     *               the objects by calling object.toString() EMPTY items won't be added.
     */
    public static String joinNotEmpty(CharSequence delimiter, Iterable tokens) {
        StringBuilder sb = new StringBuilder();
        boolean firstTime = true;
        for (Object token : tokens) {
            if (!isEmpty(toString(token))) {
                if (firstTime) {
                    firstTime = false;
                } else {
                    sb.append(delimiter);
                }
                sb.append(token);
            }
        }
        return sb.toString();
    }

    public static String firstLine(String string) {
        if (string == null) return null;
        final int nextLineIndex = string.indexOf('\n');
        if (nextLineIndex > 0) return string.substring(0, nextLineIndex);
        return string;
    }

    /**
     * Splits this strings using the supplied {@code regularExpression}.
     */
    public static List<String> splitAndClearEmpty(ArrayList<String> strings, String regularExpression) {
        ArrayList<String> result = new ArrayList<>();
        for (String string : strings) {
            result.addAll(splitAndClearEmpty(string, regularExpression));
        }
        return result;
    }

    /**
     * Splits this string using the supplied {@code regularExpression}.
     */
    public static List<String> splitAndClearEmpty(String string, String regularExpression) {
        ArrayList<String> strings = new ArrayList<>();
        final String[] split = string.split(regularExpression);
        if (split.length == 0) {
            strings.add(string);
        } else {
            strings.addAll(Arrays.asList(split));
        }

        Iterator<String> iterator = strings.iterator();
        while (iterator.hasNext()) {
            String item = iterator.next();
            if (item == null || item.trim().length() == 0) {
                iterator.remove();
            }
        }

        return strings;
    }

    /**
     * Splits this strings using the supplied {@code regularExpression}.
     */
    public static String[] splitAndClear(String[] strings, String regularExpression) {
        ArrayList<String> result = new ArrayList<>();
        for (String string : strings) {
            result.addAll(splitAndClearEmpty(string, regularExpression));
        }
        return result.toArray(new String[result.size()]);
    }

    /**
     * Splits this string using the supplied {@code regularExpression}.
     */
    public static String[] splitAndClear(String string, String regularExpression) {
        ArrayList<String> strings = new ArrayList<>();
        final String[] split = string.split(regularExpression);
        if (split == null || split.length == 0) {
            strings.add(string);
        } else {
            strings.addAll(Arrays.asList(split));
        }

        Iterator<String> iterator = strings.iterator();
        while (iterator.hasNext()) {
            String item = iterator.next();
            if (item == null || item.trim().length() == 0) {
                iterator.remove();
            }
        }

        return strings.toArray(new String[strings.size()]);
    }

    /**
     * Parse int value from string
     */
    public static int getIntValue(String intNumber) {
        try {
            return Integer.parseInt(intNumber);
        } catch (NumberFormatException e) {
            return 0;
        }
    }
}
23644
public static final Integer compare(Object a, Object b) {
        if (a==b) return 0;
        if (a==null || b==null) return null;
        assert a!=null && b!=null;
        if (a instanceof Number && b instanceof Number) {
            Number an = (Number)a;
            Number bn = (Number)b;
            if (Double.isNaN(an.doubleValue()) || Double.isNaN(bn.doubleValue())) {
                if (Double.isNaN(an.doubleValue()) && Double.isNaN(bn.doubleValue())) return 0;
                else return null;
            } else {
                if (an.doubleValue()==bn.doubleValue()) {
                    // Long.compare(long,long) is only available since Java 1.7
                    //return Long.compare(an.longValue(),bn.longValue());
                    return Long.valueOf(an.longValue()).compareTo(Long.valueOf(bn.longValue()));
                } else {
                    return Double.compare(an.doubleValue(),bn.doubleValue());
                }
            }
        } else {
            try {
                return ((Comparable)a).compareTo(b);
            } catch (Throwable e) {
                log.debug("Could not compare elements: {} - {}",a,b);
                return null;
            }
        }
    }
59168
private static boolean deepEquals(byte[] a, byte[] b) {
        return a == b || !(a == null || b == null) && Arrays.equals(a, b);
    }
705064
@Pure
	@Inline(value="($1 == $2)", constantExpression=true)
	public static boolean operator_equals(long a, double b) {
		return a == b;
	}
386882
public static boolean areEqual(Object a, Object b) {

        if (a == b) {
            return true;
        }

        if (a == null || b == null) {
            return false;
        }

        // TODO refactor the instance-ofs below

        if (a instanceof Number && b instanceof Number) {

            double delta = ((Number) a).doubleValue() - ((Number) b).doubleValue();

            // To account for floating point rounding errors, return true if
            // the difference between double a and double b is very small.
            return Math.abs(delta) < 0.00000000001;
        }

        if (AtomNode.isEmpty(a) && (b instanceof CharSequence)) {
            return ((CharSequence)b).length() == 0;
        }

        if (AtomNode.isEmpty(b) && (a instanceof CharSequence)) {
            return ((CharSequence)a).length() == 0;
        }

        if (AtomNode.isEmpty(a) && (b instanceof Collection)) {
            return ((Collection)b).size() == 0;
        }

        if (AtomNode.isEmpty(b) && (a instanceof Collection)) {
            return ((Collection)a).size() == 0;
        }

        if (AtomNode.isEmpty(a) && (b.getClass().isArray())) {
            return ((Object[])b).length == 0;
        }

        if (AtomNode.isEmpty(b) && (a.getClass().isArray())) {
            return ((Object[])a).length == 0;
        }

        return a.equals(b);
    }
979102
private final static boolean valuesMatch(Object value1, Object value2) {
        if (value1 == null) {
            return value2 == null;
        } else {
            return value1.equals(value2);
        }
    }
464548
public static boolean jsEquals(Object o1, Object o2) {
        
        // quick breakers
        if (o1 == o2) return true;
        if (o1 == null ^ o2 == null) return false;
        
        // Can we do a by-part comparison?
        if (o1 instanceof ScriptableObject && o2 instanceof ScriptableObject) {
            return jsScriptableObjectEqual((ScriptableObject) o1, (ScriptableObject) o2);
        }

        // Concatenated strings in Rhino have a different type. We need to manually
        // resolve to String semantics, which is what the following lines do.
        if (o1 instanceof ConsString) {
            o1 = o1.toString();
        }
        if (o2 instanceof ConsString) {
            o2 = o2.toString();
        }
        
        // default comparison (hopefully they have meaningful equals())
        return o1.equals(o2);
    }
180103
@Override
  public int compare(String s1, String s2) {
    if (s1 == s2) { // NOSONAR false-positive: Compare Objects With Equals
      return 0;
    }
    int h1 = s1.hashCode();
    int h2 = s2.hashCode();
    if (h1 < h2) {
      return -1;
    } else if (h1 > h2) {
      return 1;
    } else {
      return s1.compareTo(s2);
    }
  }
815718
@Pure
	@Inline(value="($1 == $2)", constantExpression=true)
	public static boolean operator_tripleEquals(short a, long b) {
		return a == b;
	}
817851
def assertEqual(cls, first, second, msg=None):
        
        asserter = None
        if type(first) is type(second):
            asserter = cls.equality_type_funcs.get(type(first))

            try:              basestring = basestring # Python 2
            except NameError: basestring = str        # Python 3

            if asserter is not None:
                if isinstance(asserter, basestring):
                    asserter = getattr(cls, asserter)

        if asserter is None:
            asserter = cls.simple_equality

        if msg is None:
            asserter(first, second)
        else:
            asserter(first, second, msg=msg)
1165990
function equals(v1, v2) {
    "use strict";
    if (isFunction(v1)) {
        return v1.toString() === v2.toString();
    }
    // with Gecko, instanceof is not enough to test object
    if (v1 instanceof Object || isObject(v1)) {
        if (!(v2 instanceof Object || isObject(v2)) ||
            Object.keys(v1).length !== Object.keys(v2).length) {
            return false;
        }
        for (var k in v1) {
            if (!equals(v1[k], v2[k])) {
                return false;
            }
        }
        return true;
    }
    return v1 === v2;
}
895988
public boolean matches(T other) {
    if (matchAny) {
      return true;
    } else if (other == null) {
      return negation ? value != null : value == null;
    } else {
      if (value instanceof byte[]) {
        boolean equal = Arrays.equals((byte[]) value, (byte[]) other);
        return negation ? !equal : equal;
      }
      return negation ? !Objects.equals(value, other) : Objects.equals(value, other);
    }