protected override Expression VisitMethodCall(MethodCallExpression node) { var state = SaveState(); var remaps = ReflectionHelper.GetCustomAttributes <ParameterDataflowAttribute>(node.Method, true); var method = node.Method; var methodParameters = method.GetParameters(); var changed = false; var arguments = new Expression[node.Arguments.Count]; var propertyAccessArray = new LooselyLinkedListNode <PropertyChainNode> [node.Arguments.Count]; var ghostAccessArray = new LooselyLinkedListNode <PropertyChainNode> [node.Arguments.Count]; for (int i = 0; i < node.Arguments.Count; i++) { var arg = node.Arguments[i]; var argument = Visit(arg); arguments[i] = argument; changed |= argument != arg; propertyAccessArray[i] = propertyAccesses.First.Next; propertyAccesses.Clear(); } Expression obj = node.Object; if (obj != null) { obj = Visit(node.Object); changed |= obj != node.Object; } var objectPropertyAccesses = propertyAccesses.First.Next; propertyAccesses.Clear(); var defaultList = Enumerable.Range(0, node.Arguments.Count).ToList(); for (int i = 0; i < node.Arguments.Count; i++) { if (propertyAccessArray[i] == null) { continue; } defaultList[i] = -2; var lambda = FindLambdaExpression(node.Arguments[i]); if (lambda != null) { var remapsforLambda = remaps.Where(a => a.FunctionIndex == i); var argumentMaps = new List <int> [lambda.Parameters.Count]; foreach (var remap in remapsforLambda) { List <int> remapForArgument = argumentMaps[remap.SourceIndex]; if (remapForArgument == null) { remapForArgument = new List <int>(); argumentMaps[remap.SourceIndex] = remapForArgument; } remapForArgument.Add(remap.FunctionParameterIndex); } for (int j = 0; j < lambda.Parameters.Count; j++) { var parameter = lambda.Parameters[j]; var dependencies = argumentMaps[j] ?? defaultList; var dummy = LooselyLinkedListNode <PropertyChainNode> .CreateDummyFor(propertyAccessArray[i]); var ghostDummy = LooselyLinkedListNode <PropertyChainNode> .CreateDummyFor(ghostAccessArray[i]); var current = dummy; var currentGhost = ghostDummy; while (current.Next != null) { if (current.Next.Value.Parameter == parameter) { var access = current.Next.Value; current.CutNext(); foreach (var dependency in dependencies) { if (dependency == -2) { continue; } PropagatePropertyAccesses(propertyAccessArray, objectPropertyAccesses, ref current, ref currentGhost, access, dependency); PropagatePropertyAccesses(ghostAccessArray, null, ref current, ref currentGhost, access, dependency); } } else { current = current.Next; } } propertyAccessArray[i] = dummy.Next; } Expression returnValue; if (ResetForLambdaExpression(state, node, lambda, out returnValue)) { return(returnValue); } } defaultList[i] = i; } if (objectPropertyAccesses != null) { propertyAccesses.AddFirst(objectPropertyAccesses); } for (int i = node.Arguments.Count - 1; i >= 0; i--) { if (propertyAccessArray[i] != null) { propertyAccesses.AddFirst(propertyAccessArray[i]); } } if (changed) { return(node.Update(obj, arguments)); } return(node); }