package com.tinkerpop.gremlin.structure;

import java.util.function.BiPredicate;

/**
 * {@link Compare} is a {@link java.util.function.BiPredicate} that determines whether the first argument is {@code ==}, {@code !=},
 * {@code >}, {@code >=}, {@code <}, {@code <=} to the second argument.
 *
 * @author Marko A. Rodriguez (http://markorodriguez.com)
 */
public enum Compare implements BiPredicate<Object, Object> {

    EQUAL, NOT_EQUAL, GREATER_THAN, GREATER_THAN_EQUAL, LESS_THAN, LESS_THAN_EQUAL;

    public boolean test(final Object first, final Object second) {
        switch (this) {
            case EQUAL:
                if (null == first)
                    return second == null;
                return first.equals(second);
            case NOT_EQUAL:
                if (null == first)
                    return second != null;
                return !first.equals(second);
            case GREATER_THAN:
                return !(null == first || second == null) && ((Comparable) first).compareTo(second) >= 1;
            case LESS_THAN:
                return !(null == first || second == null) && ((Comparable) first).compareTo(second) <= -1;
            case GREATER_THAN_EQUAL:
                return !(null == first || second == null) && ((Comparable) first).compareTo(second) >= 0;
            case LESS_THAN_EQUAL:
                return !(null == first || second == null) && ((Comparable) first).compareTo(second) <= 0;
            default:
                throw new IllegalStateException("Invalid state as no valid compare was provided");
        }
    }

    public Compare opposite() {
        if (this.equals(EQUAL))
            return NOT_EQUAL;
        else if (this.equals(NOT_EQUAL))
            return EQUAL;
        else if (this.equals(GREATER_THAN))
            return LESS_THAN_EQUAL;
        else if (this.equals(GREATER_THAN_EQUAL))
            return LESS_THAN;
        else if (this.equals(LESS_THAN))
            return GREATER_THAN_EQUAL;
        else if (this.equals(LESS_THAN_EQUAL))
            return GREATER_THAN;
        else
            throw new IllegalStateException("Comparator does not have an opposite");
    }


    public String asString() {
        if (this.equals(EQUAL))
            return "=";
        else if (this.equals(GREATER_THAN))
            return ">";
        else if (this.equals(GREATER_THAN_EQUAL))
            return ">=";
        else if (this.equals(LESS_THAN_EQUAL))
            return "<=";
        else if (this.equals(LESS_THAN))
            return "<";
        else if (this.equals(NOT_EQUAL))
            return "<>";
        else
            throw new IllegalStateException("Comparator does not have a string representation");
    }


    public static Compare fromString(final String c) {
        if (c.equals("="))
            return EQUAL;
        else if (c.equals("<>"))
            return NOT_EQUAL;
        else if (c.equals(">"))
            return GREATER_THAN;
        else if (c.equals(">="))
            return GREATER_THAN_EQUAL;
        else if (c.equals("<"))
            return LESS_THAN;
        else if (c.equals("<="))
            return LESS_THAN_EQUAL;
        else
            throw new IllegalArgumentException("String representation does not match any comparator");
    }
}

@@ -496,16 +496,55 @@
 EQUAL;%0A%0A
+%09/**%0A%09 * %7B@inheritDoc%7D%0A%09 */%0A%09@Override%0A
     publ
@@ -1617,16 +1617,105 @@
 %0A    %7D%0A%0A
+%09/**%0A%09 * Produce the opposite representation of the current %7B@code Compare%7D object.%0A%09 */%0A
     publ
@@ -2284,33 +2284,110 @@
 osite%22);%0A    %7D%0A%0A
+%09/**%0A%09 * Gets the operator representation of the %7B@code Compare%7D object.%0A%09 */
 %0A
-
     public Strin
@@ -2920,16 +2920,101 @@
 %0A    %7D%0A%0A
+%09/**%0A%09 * Get the %7B@code Compare%7D value based on the operator that represents it.%0A%09 */
 %0A    pub

Add javadoc.