// Path: src/main/java/com/github/rutledgepaulv/qbuilders/nodes/AbstractNode.java
// public abstract class AbstractNode implements Visitable {
// 
//     private LogicalNode parent;
// 
//     public AbstractNode() {}
// 
//     public AbstractNode(LogicalNode parent) {
//         this.parent = parent;
//     }
// 
//     public LogicalNode getParent() {
//         return parent;
//     }
// 
//     public void setParent(LogicalNode parent) {
//         this.parent = parent;
//     }
// 
//     @Override
//     public <T, S> T visit(ContextualNodeVisitor<T, S> visitor, S context) {
//         return visitor.visitAny(this, context);
//     }
// 
// }
// 
// Path: src/main/java/com/github/rutledgepaulv/qbuilders/nodes/AndNode.java
// public final class AndNode extends LogicalNode {
// 
//     public AndNode() {}
// 
//     public AndNode(LogicalNode parent) {
//         super(parent);
//     }
// 
//     public AndNode(LogicalNode parent, List<AbstractNode> children) {
//         super(parent, children);
//     }
// 
// }
// 
// Path: src/main/java/com/github/rutledgepaulv/qbuilders/nodes/ComparisonNode.java
// public final class ComparisonNode extends AbstractNode {
// 
//     private FieldPath path;
//     private ComparisonOperator operator;
//     private Collection<?> values;
// 
//     public ComparisonNode(LogicalNode parent) {
//         super(parent);
//     }
// 
//     public FieldPath getField() {
//         return path;
//     }
// 
//     public void setField(FieldPath field) {
//         this.path = field;
//     }
// 
//     public ComparisonOperator getOperator() {
//         return operator;
//     }
// 
//     public void setOperator(ComparisonOperator operator) {
//         this.operator = operator;
//     }
// 
//     public Collection<?> getValues() {
//         return values;
//     }
// 
//     public void setValues(Collection<?> values) {
//         this.values = values;
//     }
// }
// 
// Path: src/main/java/com/github/rutledgepaulv/qbuilders/nodes/OrNode.java
// public final class OrNode extends LogicalNode {
// 
//     public OrNode() {}
// 
//     public OrNode(LogicalNode parent) {
//         super(parent);
//     }
// 
//     public OrNode(LogicalNode parent, List<AbstractNode> children) {
//         super(parent, children);
//     }
// 
// 
// }
// 
// Path: src/main/java/com/github/rutledgepaulv/qbuilders/operators/ComparisonOperator.java
// public final class ComparisonOperator {
// 
//     private String representation;
// 
//     public ComparisonOperator(String representation) {
//         this.representation = representation;
//     }
// 
//     public static final ComparisonOperator EQ = new ComparisonOperator("EQ");
//     public static final ComparisonOperator NE = new ComparisonOperator("NE");
//     public static final ComparisonOperator GT = new ComparisonOperator("GT");
//     public static final ComparisonOperator LT = new ComparisonOperator("LT");
//     public static final ComparisonOperator GTE = new ComparisonOperator("GTE");
//     public static final ComparisonOperator LTE = new ComparisonOperator("LTE");
//     public static final ComparisonOperator IN = new ComparisonOperator("IN");
//     public static final ComparisonOperator NIN = new ComparisonOperator("NIN");
//     public static final ComparisonOperator EX = new ComparisonOperator("EX");
//     public static final ComparisonOperator RE = new ComparisonOperator("RE");
//     public static final ComparisonOperator SUB_CONDITION_ANY = new ComparisonOperator("SUB_CONDITION_ANY");
// 
//     @Override
//     public final boolean equals(Object o) {
//         if (this == o) {
//             return true;
//         }
//         if (o == null || getClass() != o.getClass()) {
//             return false;
//         }
//         ComparisonOperator that = (ComparisonOperator) o;
//         return Objects.equals(representation, that.representation);
//     }
// 
//     @Override
//     public final int hashCode() {
//         return Objects.hash(representation);
//     }
// }


import com.github.rutledgepaulv.qbuilders.nodes.AbstractNode;
import com.github.rutledgepaulv.qbuilders.nodes.AndNode;
import com.github.rutledgepaulv.qbuilders.nodes.ComparisonNode;
import com.github.rutledgepaulv.qbuilders.nodes.OrNode;
import com.github.rutledgepaulv.qbuilders.operators.ComparisonOperator;
import java.util.Objects;
import java.util.function.Function;
import static java.util.stream.Collectors.joining;
            return single(node, "==");
        } else if(ComparisonOperator.NE.equals(operator)) {
            return single(node, "!=");
        } else if (ComparisonOperator.EX.equals(operator)) {
            return single(node, "=ex=");
        } else if (ComparisonOperator.GT.equals(operator)) {
            return single(node, "=gt=");
        } else if (ComparisonOperator.LT.equals(operator)) {
            return single(node, "=lt=");
        } else if (ComparisonOperator.GTE.equals(operator)) {
            return single(node, "=ge=");
        } else if (ComparisonOperator.LTE.equals(operator)) {
            return single(node, "=le=");
        } else if (ComparisonOperator.IN.equals(operator)) {
            return list(node, "=in=");
        } else if (ComparisonOperator.NIN.equals(operator)) {
            return list(node, "=out=");
        } else if (ComparisonOperator.RE.equals(operator)) {
            return single(node, "=re=");
        } else if (ComparisonOperator.SUB_CONDITION_ANY.equals(operator)) {
            return node.getField().asKey() + "=q=" + serialize(condition(node));
        }

        throw new UnsupportedOperationException("This visitor does not support the operator " + operator + ".");
    }

    protected boolean nodeBelongsToParentExpression(AbstractNode node) {
        return node.getParent() != null;
    }

// Path: src/main/java/com/github/rutledgepaulv/qbuilders/nodes/AbstractNode.java
// public abstract class AbstractNode implements Visitable {
// 
//     private LogicalNode parent;
// 
//     public AbstractNode() {}
// 
//     public AbstractNode(LogicalNode parent) {
//         this.parent = parent;
//     }
// 
//     public LogicalNode getParent() {
//         return parent;
//     }
// 
//     public void setParent(LogicalNode parent) {
//         this.parent = parent;
//     }
// 
//     @Override
//     public <T, S> T visit(ContextualNodeVisitor<T, S> visitor, S context) {
//         return visitor.visitAny(this, context);
//     }
// 
// }
// 
// Path: src/main/java/com/github/rutledgepaulv/qbuilders/nodes/AndNode.java
// public final class AndNode extends LogicalNode {
// 
//     public AndNode() {}
// 
//     public AndNode(LogicalNode parent) {
//         super(parent);
//     }
// 
//     public AndNode(LogicalNode parent, List<AbstractNode> children) {
//         super(parent, children);
//     }
// 
// }
// 
// Path: src/main/java/com/github/rutledgepaulv/qbuilders/nodes/ComparisonNode.java
// public final class ComparisonNode extends AbstractNode {
// 
//     private FieldPath path;
//     private ComparisonOperator operator;
//     private Collection<?> values;
// 
//     public ComparisonNode(LogicalNode parent) {
//         super(parent);
//     }
// 
//     public FieldPath getField() {
//         return path;
//     }
// 
//     public void setField(FieldPath field) {
//         this.path = field;
//     }
// 
//     public ComparisonOperator getOperator() {
//         return operator;
//     }
// 
//     public void setOperator(ComparisonOperator operator) {
//         this.operator = operator;
//     }
// 
//     public Collection<?> getValues() {
//         return values;
//     }
// 
//     public void setValues(Collection<?> values) {
//         this.values = values;
//     }
// }
// 
// Path: src/main/java/com/github/rutledgepaulv/qbuilders/nodes/OrNode.java
// public final class OrNode extends LogicalNode {
// 
//     public OrNode() {}
// 
//     public OrNode(LogicalNode parent) {
//         super(parent);
//     }
// 
//     public OrNode(LogicalNode parent, List<AbstractNode> children) {
//         super(parent, children);
//     }
// 
// 
// }
// 
// Path: src/main/java/com/github/rutledgepaulv/qbuilders/operators/ComparisonOperator.java
// public final class ComparisonOperator {
// 
//     private String representation;
// 
//     public ComparisonOperator(String representation) {
//         this.representation = representation;
//     }
// 
//     public static final ComparisonOperator EQ = new ComparisonOperator("EQ");
//     public static final ComparisonOperator NE = new ComparisonOperator("NE");
//     public static final ComparisonOperator GT = new ComparisonOperator("GT");
//     public static final ComparisonOperator LT = new ComparisonOperator("LT");
//     public static final ComparisonOperator GTE = new ComparisonOperator("GTE");
//     public static final ComparisonOperator LTE = new ComparisonOperator("LTE");
//     public static final ComparisonOperator IN = new ComparisonOperator("IN");
//     public static final ComparisonOperator NIN = new ComparisonOperator("NIN");
//     public static final ComparisonOperator EX = new ComparisonOperator("EX");
//     public static final ComparisonOperator RE = new ComparisonOperator("RE");
//     public static final ComparisonOperator SUB_CONDITION_ANY = new ComparisonOperator("SUB_CONDITION_ANY");
// 
//     @Override
//     public final boolean equals(Object o) {
//         if (this == o) {
//             return true;
//         }
//         if (o == null || getClass() != o.getClass()) {
//             return false;
//         }
//         ComparisonOperator that = (ComparisonOperator) o;
//         return Objects.equals(representation, that.representation);
//     }
// 
//     @Override
//     public final int hashCode() {
//         return Objects.hash(representation);
//     }
// }


// Path: src/main/java/com/github/rutledgepaulv/qbuilders/visitors/RSQLVisitor.java
import com.github.rutledgepaulv.qbuilders.nodes.AbstractNode;
import com.github.rutledgepaulv.qbuilders.nodes.AndNode;
import com.github.rutledgepaulv.qbuilders.nodes.ComparisonNode;
import com.github.rutledgepaulv.qbuilders.nodes.OrNode;
import com.github.rutledgepaulv.qbuilders.operators.ComparisonOperator;
import java.util.Objects;
import java.util.function.Function;
import static java.util.stream.Collectors.joining;

            return single(node, "==");
        } else if(ComparisonOperator.NE.equals(operator)) {
            return single(node, "!=");
        } else if (ComparisonOperator.EX.equals(operator)) {
            return single(node, "=ex=");
        } else if (ComparisonOperator.GT.equals(operator)) {
            return single(node, "=gt=");
        } else if (ComparisonOperator.LT.equals(operator)) {
            return single(node, "=lt=");
        } else if (ComparisonOperator.GTE.equals(operator)) {
            return single(node, "=ge=");
        } else if (ComparisonOperator.LTE.equals(operator)) {
            return single(node, "=le=");
        } else if (ComparisonOperator.IN.equals(operator)) {
            return list(node, "=in=");
        } else if (ComparisonOperator.NIN.equals(operator)) {
            return list(node, "=out=");
        } else if (ComparisonOperator.RE.equals(operator)) {
            return single(node, "=re=");
        } else if (ComparisonOperator.SUB_CONDITION_ANY.equals(operator)) {
            return node.getField().asKey() + "=q=" + serialize(condition(node));
        }

        throw new UnsupportedOperationException("This visitor does not support the operator " + operator + ".");
    }

    protected boolean nodeBelongsToParentExpression(AbstractNode node) {
        return node.getParent() != null;
    }

    protected String single(ComparisonNode node, String op) {