//"x in y" should return true whenever "for (var z in y) if (z === x) return true" returns true
public static bool JScriptIn(Object v1, Object v2){
bool result = false;
if (v2 is ScriptObject)
return !(((ScriptObject)v2).GetMemberValue(Convert.ToString(v1)) is Missing);
else if (v2 is Array){
Array arr = (Array)v2;
double d = Convert.ToNumber(v1);
int i = (int)d;
return d == i && arr.GetLowerBound(0) <= i && i <= arr.GetUpperBound(0);
}else if (v2 is IEnumerable){
if (v1 == null) return false;
//Do not enumerate when a direct lookup is available
if (v2 is IDictionary)
return ((IDictionary)v2).Contains(v1);
if (v2 is IExpando){
MemberInfo[] members = ((IReflect)v2).GetMember(Convert.ToString(v1), BindingFlags.Instance|BindingFlags.DeclaredOnly|BindingFlags.Public);
return members.Length > 0;
}
IEnumerator enu = ((IEnumerable)v2).GetEnumerator();
while (!result && enu.MoveNext())
if (v1.Equals(enu.Current)) return true;
}else if (v2 is IEnumerator){
if (v1 == null) return false;
IEnumerator enu = (IEnumerator)v2;
while (!result && enu.MoveNext())
if (v1.Equals(enu.Current)) return true;
}
throw new JScriptException(JSError.ObjectExpected);
}