Greater support for non-strict equality/inequality variations between XMLish operands, and potentially other types. Requires update in Framework XML lib.
diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/BinaryOperatorEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/BinaryOperatorEmitter.java
index 33a2dd8..38a3f3e 100644
--- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/BinaryOperatorEmitter.java
+++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/BinaryOperatorEmitter.java
@@ -515,7 +515,7 @@
 				if (leftDef != null && leftDef.getQualifiedName().equals("QName")) {
 					IDefinition rightDef = node.getRightOperandNode().resolveType(getProject());
 					if (rightDef != null && rightDef.getQualifiedName().equals("QName")) {
-						//handle non-strict equality/inequality a little differently
+						//handle non-strict equality/inequality a little differently via QName.equality method
 						if (id == ASTNodeID.Op_NotEqualID) write("!");
 						write("QName.equality(");
 						getWalker().walk(node.getLeftOperandNode());
@@ -524,38 +524,82 @@
 						write(")");
 						return;
 					}
-				} else if (leftDef != null && getProject().getBuiltinType(BuiltinType.BOOLEAN).equals(leftDef) && SemanticUtils.isXMLish(node.getRightOperandNode(), getProject())) {
-					boolean literalBool = node.getLeftOperandNode().getNodeID() == ASTNodeID.LiteralBooleanID;
-					//note, this only covers boolean ==/!= xmlish, not: xmlish ==/!= boolean
-					if (literalBool) {
-						write("'");
+				} else {
+					IASNode codeContext = node.getAncestorOfType(IClassNode.class);
+					boolean isFrameworkXML = false;
+					if (codeContext instanceof IClassNode) {
+						if (((IClassNode) codeContext).getQualifiedName().equals("XML") || ((IClassNode) codeContext).getQualifiedName().equals("XMLList")) {
+							//we will ignore the internal code of the emulation support classes for these cases
+							isFrameworkXML = true;
+						}
 					}
-					else write("('' + ");
-						getWalker().walk(node.getLeftOperandNode());
-					if (literalBool) {
-						write("'");
-					}
-					else write(")");
-					write(" " + node.getOperator().getOperatorText() + " ");
+					if (!isFrameworkXML) {
+						boolean leftIsAny = (leftDef == null || getProject().getBuiltinType(BuiltinType.ANY_TYPE).equals(leftDef));
+						IDefinition rightDef = node.getRightOperandNode().resolveType(getProject());
+						boolean rightIsAny = (rightDef == null || getProject().getBuiltinType(BuiltinType.ANY_TYPE).equals(rightDef));
+						boolean leftIsXMLish = (leftIsAny && SemanticUtils.isXMLish(node.getLeftOperandNode(), getProject())) || SemanticUtils.isXMLish(leftDef, getProject());
+						boolean rightIsXMLish = (rightIsAny && SemanticUtils.isXMLish(node.getRightOperandNode(), getProject())) || SemanticUtils.isXMLish(rightDef, getProject());
 
-					getWalker().walk(node.getRightOperandNode());
-					return;
-				} else if ((((leftDef == null || getProject().getBuiltinType(BuiltinType.ANY_TYPE).equals(leftDef)) && SemanticUtils.isXMLish(node.getLeftOperandNode(), getProject())) || SemanticUtils.isXMLish(leftDef, getProject())) && getProject().getBuiltinType(BuiltinType.BOOLEAN).equals(node.getRightOperandNode().resolveType(getProject()))) {
-					boolean literalBool = node.getRightOperandNode().getNodeID() == ASTNodeID.LiteralBooleanID;
 
-					//note, this only covers xmlish ==/!= boolean, not: boolean ==/!= xmlish
-					getWalker().walk(node.getLeftOperandNode());
-					write(" " + node.getOperator().getOperatorText() + " ");
-					if (literalBool) {
-						write("'");
+						if (leftIsXMLish && rightIsXMLish) {
+
+
+							startMapping(node, node.getLeftOperandNode());
+							//handle non-strict equality/inequality for XMLish comparisons a little differently
+							if (id == ASTNodeID.Op_NotEqualID) write("!");
+							write("XML.equality(");
+							endMapping(node);
+							getWalker().walk(node.getLeftOperandNode());
+							startMapping(node, node.getLeftOperandNode());
+							write(",");
+							endMapping(node);
+							getWalker().walk(node.getRightOperandNode());
+							startMapping(node, node.getLeftOperandNode());
+							write(")");
+							endMapping(node);
+							return;
+						} else {
+							if (leftIsXMLish || rightIsXMLish) {
+
+								IDefinition otherDef = leftIsXMLish ? rightDef : leftDef;
+								boolean otherIsBoolean = getProject().getBuiltinType(BuiltinType.BOOLEAN).equals(otherDef);
+
+
+								if (otherIsBoolean || (leftIsAny && rightIsXMLish) || (rightIsAny && leftIsXMLish)) {
+
+									if (otherIsBoolean) {
+										//cover xmlish ==/!= boolean and boolean ==/!= xmlish variations by converting the boolean value to string (xmlishBooleanEqualityOperand):
+										if (leftIsXMLish) getWalker().walk(node.getLeftOperandNode());
+										else xmlishBooleanEqualityOperand(node.getLeftOperandNode());
+										write(" " + node.getOperator().getOperatorText() + " ");
+										if (leftIsXMLish) xmlishBooleanEqualityOperand(node.getRightOperandNode());
+										else getWalker().walk(node.getRightOperandNode());
+										return;
+									} else {
+										//cover xmlish ==/!= * (typed) and * (typed) ==/!= xmlish variations:
+										IExpressionNode lhs = leftIsXMLish ? node.getLeftOperandNode() : node.getRightOperandNode();
+										IExpressionNode rhs = leftIsXMLish ? node.getRightOperandNode() : node.getLeftOperandNode();
+										//@todo check the source-mapping to the equality/inequality operator, this could probably be improved:
+										startMapping(node, node.getLeftOperandNode());
+										//handle non-strict equality/inequality for XMLish comparisons a little differently via XML.mixedEquality method
+										if (id == ASTNodeID.Op_NotEqualID) write("!");
+
+										write("XML.mixedEquality(");
+										endMapping(node);
+										getWalker().walk(lhs);
+										startMapping(node, node.getLeftOperandNode());
+										write(",");
+										endMapping(node);
+										getWalker().walk(rhs);
+										startMapping(node, node.getLeftOperandNode());
+										write(")");
+										endMapping(node);
+										return;
+									}
+								}
+							}
+						}
 					}
-					else write("('' + ");
-					getWalker().walk(node.getRightOperandNode());
-					if (literalBool) {
-						write("'");
-					}
-					else write(")");
-					return;
 				}
 			}
 			
@@ -563,6 +607,17 @@
 			super_emitBinaryOperator(node, isAssignment);
         }
     }
+
+	private void xmlishBooleanEqualityOperand(IExpressionNode booleanOperandNode) {
+		boolean literalBool = booleanOperandNode.getNodeID() == ASTNodeID.LiteralBooleanID;
+		if (literalBool) {
+			write("'");
+		} else write("('' + ");
+		getWalker().walk(booleanOperandNode);
+		if (literalBool) {
+			write("'");
+		} else write(")");
+	}
     
 
     private void super_emitBinaryOperator(IBinaryOperatorNode node, boolean isAssignment)