protected override Expression VisitMethodCall(MethodCallExpression node) { var parameterExpression = node.GetParameterExpression(); if (parameterExpression == null) { return(base.VisitMethodCall(node)); } InfoDictionary.Add(parameterExpression, TypeMappings); var listOfArgumentsForNewMethod = node.Arguments.Aggregate(new List <Expression>(), (lst, next) => { var mappedNext = ArgumentMapper.Create(this, next).MappedArgumentExpression; TypeMappings.AddTypeMapping(next.Type, mappedNext.Type); lst.Add(mappedNext); return(lst); });//Arguments could be expressions or other objects. e.g. s => s.UserId or a string "ZZZ". For extention methods node.Arguments[0] is usually the helper object itself //type args are the generic type args e.g. T1 and T2 MethodName<T1, T2>(method arguments); var typeArgsForNewMethod = node.Method.IsGenericMethod ? node.Method.GetGenericArguments().Select(i => TypeMappings.ContainsKey(i) ? TypeMappings[i] : i).ToList()//not converting the type it is not in the typeMappings dictionary : null; MethodCallExpression resultExp; if (!node.Method.IsStatic) { var instance = ArgumentMapper.Create(this, node.Object).MappedArgumentExpression; resultExp = node.Method.IsGenericMethod ? Expression.Call(instance, node.Method.Name, typeArgsForNewMethod.ToArray(), listOfArgumentsForNewMethod.ToArray()) : Expression.Call(instance, node.Method, listOfArgumentsForNewMethod.ToArray()); } else { resultExp = node.Method.IsGenericMethod ? Expression.Call(node.Method.DeclaringType, node.Method.Name, typeArgsForNewMethod.ToArray(), listOfArgumentsForNewMethod.ToArray()) : Expression.Call(node.Method, listOfArgumentsForNewMethod.ToArray()); } return(resultExp); }