SLING-7688 - [HTL] Add support for the in relational operator
diff --git a/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/JavaSource.java b/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/JavaSource.java
index 680e340..cebb2ae 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/JavaSource.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/JavaSource.java
@@ -252,6 +252,10 @@
         return property(className, "class").startCall("getName", true).endCall();
     }
 
+    public JavaSource instanceOf(String className) {
+        return append(" instanceof ").append(className);
+    }
+
     private StringBuilder indent() {
         for (int i = 0; i < indentLevel; i++) {
             builder.append(INDENT);
diff --git a/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/operator/InOpGen.java b/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/operator/InOpGen.java
new file mode 100644
index 0000000..c73c839
--- /dev/null
+++ b/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/operator/InOpGen.java
@@ -0,0 +1,50 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements.  See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership.  The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License.  You may obtain a copy of the License at
+ ~
+ ~   http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied.  See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+package org.apache.sling.scripting.sightly.java.compiler.impl.operator;
+
+import org.apache.sling.scripting.sightly.compiler.expression.nodes.BinaryOperator;
+import org.apache.sling.scripting.sightly.java.compiler.impl.ExpressionTranslator;
+import org.apache.sling.scripting.sightly.java.compiler.impl.JavaSource;
+import org.apache.sling.scripting.sightly.java.compiler.impl.SourceGenConstants;
+import org.apache.sling.scripting.sightly.java.compiler.impl.Type;
+
+/**
+ * Operator generator for {@link BinaryOperator#IN}.
+ */
+public class InOpGen implements BinaryOpGen {
+
+    @Override
+    public Type returnType(Type leftType, Type rightType) {
+        return Type.BOOLEAN;
+    }
+
+    @Override
+    public void generate(JavaSource source, ExpressionTranslator visitor, TypedNode left, TypedNode right) {
+        source.startMethodCall(BinaryOperator.class.getName(), "inOp");
+        left.getNode().accept(visitor);
+        source.separateArgument();
+        right.getNode().accept(visitor);
+        source.instanceOf("String").conditional();
+        right.getNode().accept(visitor);
+        source.conditionalBranchSep().objectModel().startCall(SourceGenConstants.ROM_TO_COLLECTION, true);
+        right.getNode().accept(visitor);
+        source.endCall();
+        source.endCall();
+    }
+}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/operator/Operators.java b/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/operator/Operators.java
index a90e332..c445b29 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/operator/Operators.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/operator/Operators.java
@@ -51,6 +51,7 @@
         representationMap.put(BinaryOperator.GEQ, new ComparisonOpGen(BinaryOperator.GEQ));
         representationMap.put(BinaryOperator.STRICT_EQ, new StrictEqGenOp(false));
         representationMap.put(BinaryOperator.STRICT_NEQ, new StrictEqGenOp(true));
+        representationMap.put(BinaryOperator.IN, new InOpGen());
 
         unaryMapping.put(UnaryOperator.LENGTH, LengthOpGen.INSTANCE);
         unaryMapping.put(UnaryOperator.IS_WHITESPACE, IsWhiteSpaceGen.INSTANCE);