DynamicInvoke() private method

private DynamicInvoke ( Expression e ) : object
e System.Linq.Expressions.Expression
return object
        static bool CheckArgument(ExpressionParser parser, MethodCallExpression methE, bool left, out string hint)
        {
            int ix1 = left ? 0 : 1;
            int ix2 = left ? 1 : 0;

            if (typeof (Delegate).IsAssignableFrom(methE.Arguments[ix1].Type))
            {
                object leftR;
                try
                {
                    leftR = parser.DynamicInvoke(Expression.Invoke(methE.Arguments[ix1]));
                }
                catch (InvalidOperationException) // delegate needs arguments
                {
                    hint = null;
                    return false;
                }

                if (Equals(leftR, parser.DynamicInvoke(methE.Arguments[ix2])))
                {
                    hint = string.Format(", but would have been True if you had invoked '{0}'",
                        NodeFormatter.PrettyPrint(parser.Parse(methE.Arguments[ix1])));
                    return true;
                }
            }

            hint = null;
            return false;
        }
        public bool TryGetHint(ExpressionParser parser, Expression expression, out string hint)
        {
            var methE = expression as MethodCallExpression;
            if (methE != null)
            {
                if (methE.Method == ObjectEqualsMethodInfo)
                {
                    var left = parser.DynamicInvoke(methE.Arguments[0]);
                    var right = parser.DynamicInvoke(methE.Arguments[1]);

                    if (left is Delegate || right is Delegate)
                    {
                        if (CheckArgument(parser, methE, true, out hint))
                        {
                            return true;
                        }

                        if (CheckArgument(parser, methE, false, out hint))
                        {
                            return true;
                        }

                        hint = ", this is a suspicious comparison";
                        return true;
                    }
                }
            }

            hint = null;
            return false;
        }
        public bool TryGetHint(ExpressionParser parser, Expression expression, out string hint)
        {
            object left = null;
            object right = null;
            Type declaringType = null;

            var methE = expression as MethodCallExpression;
            if (methE != null)
            {
                if (methE.Method == ObjectEqualsMethodInfo)
                {
                    left = parser.DynamicInvoke(methE.Object);
                    right = parser.DynamicInvoke(methE.Arguments[0]);

                    // methE.Method.DeclaringType doesn't work here, it will
                    // always return the base class method
                    declaringType = GetDerivedMethodInfo(methE.Object.Type, methE.Method).DeclaringType;
                }
            }

            var binE = expression as BinaryExpression;
            if (binE != null && binE.NodeType == ExpressionType.Equal)
            {
                left = parser.DynamicInvoke(binE.Left);
                right = parser.DynamicInvoke(binE.Right);

                if (binE.Method != null)
                {
                    declaringType = binE.Method.DeclaringType;
                }
                else
                {
                    declaringType = typeof (object); // this should never happen - the hints are only called when the assert fails
                }
            }

            if (left != null && left == right)
            {
                hint = ", type " + ExpressionParser.NameOfType(declaringType) + " has a broken equality implementation (both sides are the same object)";
                return true;
            }

            hint = null;
            return false;
        }
        public bool TryGetHint(ExpressionParser parser, Expression expression, out string hint)
        {
            var methE = expression as MethodCallExpression;
            if (methE != null)
            {
                if (StringEqualsMethodInfo.Any(x => x == methE.Method))
                {
                    var obj = parser.DynamicInvoke(methE.Object);
                    var arg = parser.DynamicInvoke(methE.Arguments.First());

                    var comparison = (StringComparison) (methE.Arguments.Select(parser.DynamicInvoke)
                        .FirstOrDefault(x => x is StringComparison) ?? StringComparison.CurrentCulture);

                    hint = HintUtils.GetStringDifferHint((string) obj, (string) arg, GetComparerFromComparison(comparison));
                    return hint != null;
                }
            }

            hint = null;
            return false;
        }
        public bool TryGetHint(ExpressionParser parser, Expression expression, out string hint)
        {
            var methE = expression as MethodCallExpression;
            if (methE != null)
            {
                if (methE.Method == ObjectInstanceEqualsMethodInfo)
                {
                    var obj = parser.DynamicInvoke(methE.Object) as IEnumerable;
                    var arg = parser.DynamicInvoke(methE.Arguments.First()) as IEnumerable;
                    if (obj != null && arg != null)
                    {
                        if (obj.Cast<object>().SequenceEqual(arg.Cast<object>()))
                        {
                            hint = ", but would have been True with .SequenceEqual()";
                            return true;
                        }
                    }
                }
            }

            hint = null;
            return false;
        }
                                                         x.GetParameters().Count() == 2); // TODO: equality comparer support

        public bool TryGetHint(ExpressionParser parser, Expression expression, out string hint)
        {
            var methE = expression as MethodCallExpression;
            if (methE != null)
            {
                var typeParams = methE.Method.GetGenericArguments();
                if (typeParams.Count() == 1)
                {
                    var instantiatedMethodInfo = SequenceEqualMethodInfo.MakeGenericMethod(typeParams);
                    if (methE.Method == instantiatedMethodInfo)
                    {
                        var left = parser.DynamicInvoke(methE.Arguments[0]);
                        var right = parser.DynamicInvoke(methE.Arguments[1]);

                        var enumLeft = ((IEnumerable) left).GetEnumerator();
                        var enumRight = ((IEnumerable) right).GetEnumerator();
                        {
                            int i = 0;
                            while (enumLeft.MoveNext() && enumRight.MoveNext())
                            {
                                if (!Equals(enumLeft.Current, enumRight.Current))
                                {
                                    hint = string.Format(", enumerables differ at index {0}, {1} != {2}", i,
                                        ObjectFormatter.FormatObject(enumLeft.Current),
                                        ObjectFormatter.FormatObject(enumRight.Current));
                                    return true;
                                }
                                ++i;
                            }
                        }
                    }
                }
            }

            hint = null;
            return false;
        }
        public bool TryGetHint(ExpressionParser parser, Expression expression, out string hint)
        {
            if (expression is BinaryExpression && expression.NodeType == ExpressionType.Equal)
            {
                var be = (BinaryExpression) expression;
                object left;
                object right;
                try
                {
                    left = parser.DynamicInvoke(be.Left);
                    right = parser.DynamicInvoke(be.Right);
                }
                catch (TargetInvocationException exception)
                {
                    hint = ObjectFormatter.FormatTargetInvocationException(exception);
                    return true;
                }

                return TryGetHint(parser, left, right, out hint);
            }

            hint = null;
            return false;
        }
 string Parse(ExpressionParser parser, Type enumType, Expression expression)
 {
     return enumType.Name + "." + Enum.GetName(enumType, parser.DynamicInvoke(expression));
 }