internal ResolveResult ResolveLambda(ResolveVisitor visitor, Expression lambdaExpression)
            {
                if (expressions.Contains(lambdaExpression))
                {
                    return(null);
                }
                expressions.Add(lambdaExpression);
                if (lambdaExpression.Parent is LambdaExpression)
                {
                    return(ResolveLambda(visitor, lambdaExpression.Parent as Expression));
                }
                if (lambdaExpression.Parent is ParenthesizedExpression)
                {
                    return(ResolveLambda(visitor, lambdaExpression.Parent as Expression));
                }
                if (lambdaExpression.Parent is AssignmentExpression)
                {
                    return(visitor.Resolve(((AssignmentExpression)lambdaExpression.Parent).Left));
                }
                if (lambdaExpression.Parent is CastExpression)
                {
                    return(visitor.Resolve(((CastExpression)lambdaExpression.Parent)));
                }
                if (lambdaExpression.Parent is VariableDeclaration)
                {
                    VariableDeclaration varDec = (VariableDeclaration)lambdaExpression.Parent;
                    return(resolver.GetFunctionParameterType(resolver.ResolveIdentifier(visitor, varDec.Name)));
                }
                if (lambdaExpression.Parent is InvocationExpression)
                {
                    LambdaExpression lambda           = (LambdaExpression)lambdaExpression;
                    ResolveResult    lambdaReturnType = null;
                    if (!lambda.ExpressionBody.IsNull)
                    {
                        DomLocation old = resolver.resolvePosition;
                        try {
                            resolver.resolvePosition = new DomLocation((resolver.CallingMember != null ? resolver.CallingMember.Location.Line : 0) +
                                                                       lambda.ExpressionBody.StartLocation.Line - 2,
                                                                       lambda.ExpressionBody.StartLocation.Column - 1);
                            lambdaReturnType = visitor.Resolve(lambda.ExpressionBody);
                        } finally {
                            resolver.resolvePosition = old;
                        }
                    }

                    InvocationExpression invocation = (InvocationExpression)lambdaExpression.Parent;
                    MethodResolveResult  result     = visitor.Resolve(invocation.TargetObject) as MethodResolveResult;
                    if (result == null)
                    {
                        MonoDevelop.Core.LoggingService.LogWarning("No compatible method found :" + invocation.TargetObject);
                        return(null);
                    }
                    result.ResolveExtensionMethods();

                    for (int i = 0; i < invocation.Arguments.Count; i++)
                    {
                        if (invocation.Arguments[i] == lambdaExpression && i < result.MostLikelyMethod.Parameters.Count)
                        {
                            IParameter  parameter  = result.MostLikelyMethod.Parameters[i];
                            IReturnType returnType = parameter.ReturnType;
                            IType       type       = resolver.Dom.GetType(returnType);

                            bool isResolved = false;
                            if (type != null && type.ClassType == MonoDevelop.Projects.Dom.ClassType.Delegate)
                            {
                                IMethod invocationMethod = type.Methods.First();
                                if (invocationMethod.Parameters.Count > 0)
                                {
                                    if (lambdaReturnType == null || lambdaReturnType.ResolvedType == null || string.IsNullOrEmpty(lambdaReturnType.ResolvedType.FullName))
                                    {
                                        returnType = invocationMethod.Parameters[System.Math.Min(i, invocationMethod.Parameters.Count - 1)].ReturnType;
                                    }
                                    else
                                    {
                                        returnType = (IReturnType) new TypeReplaceVisitor(invocationMethod.ReturnType, lambdaReturnType.ResolvedType).Visit(returnType, null);
                                    }
                                    isResolved = true;
                                }
                            }

                            if (!isResolved)
                            {
                                while (returnType.GenericArguments.Count > 0)
                                {
                                    returnType = returnType.GenericArguments[0];
                                }
                            }
                            string invariantString = returnType.ToInvariantString();
                            if (returnTypeDictionary.ContainsKey(invariantString))
                            {
                                return(returnTypeDictionary[invariantString]);
                            }
                            ResolveResult createdResult = visitor.CreateResult(returnType);
//							if (!(returnType.Type is AnonymousType))
                            returnTypeDictionary[invariantString] = createdResult;
                            return(createdResult);
                        }
                    }

                    if (lambdaReturnType != null && !string.IsNullOrEmpty(lambdaReturnType.ResolvedType.FullName))
                    {
                        return(lambdaReturnType);
                    }

                    foreach (Expression arg in invocation.Arguments)
                    {
                        var argType = arg is LambdaExpression ?  DomReturnType.Void : visitor.GetTypeSafe(arg);
                        result.AddArgument(argType);
                    }

                    result.ResolveExtensionMethods();
                    //Console.WriteLine ("maybe method:" + result.MostLikelyMethod);
                    for (int i = 0; i < invocation.Arguments.Count; i++)
                    {
                        if (invocation.Arguments [i] == lambdaExpression && i < result.MostLikelyMethod.Parameters.Count)
                        {
                            IParameter parameterType = result.MostLikelyMethod.Parameters [i];
                            //Console.WriteLine (i + " par: " + parameterType);
                            if (parameterType.ReturnType.Name == "Func" && parameterType.ReturnType.GenericArguments.Count > 0)
                            {
                                return(visitor.CreateResult(parameterType.ReturnType.GenericArguments[0]));
                            }
                        }
                    }
                    return(result);
                }

                if (lambdaExpression.Parent is ObjectCreateExpression)
                {
                    ObjectCreateExpression objectCreateExpression = (ObjectCreateExpression)lambdaExpression.Parent;
                    int index = objectCreateExpression.Parameters.IndexOf(lambdaExpression);
                    if (index < 0)
                    {
                        return(null);
                    }
                    MemberResolveResult resolvedCreateExpression = visitor.Resolve(objectCreateExpression) as MemberResolveResult;

                    if (resolvedCreateExpression != null)
                    {
                        IMethod method = resolvedCreateExpression.ResolvedMember as IMethod;
                        if (method != null && index < method.Parameters.Count)
                        {
                            return(new ParameterResolveResult(method.Parameters[index]));
                        }
                        else
                        {
                            return(null);
                        }
                    }
                }

                return(null);
            }
        public ResolveResult ResolveIdentifier(ResolveVisitor visitor, string identifier)
        {
            ResolveResult result = null;

            if (resultTable.TryGetValue(identifier, out result))
            {
                return(result);
            }
            resultTable[identifier] = result;
//			Console.WriteLine (lookupVariableLine);
            foreach (KeyValuePair <string, List <LocalLookupVariable> > pair in this.lookupTableVisitor.Variables)
            {
                if (identifier == pair.Key)
                {
                    LocalLookupVariable var = null;
//					Console.WriteLine ("--- RP:" + this.resolvePosition + "/" + pair.Value.Count);
                    foreach (LocalLookupVariable v2 in pair.Value)
                    {
                        DomLocation varStartPos = new DomLocation(lookupVariableLine + v2.StartPos.Line, v2.StartPos.Column - 1);
                        DomLocation varEndPos   = new DomLocation(lookupVariableLine + v2.EndPos.Line, v2.EndPos.Column - 1);
//						Console.WriteLine (v2.Name + ":" + varStartPos + " <> " + varEndPos + " resolve position:" + this.resolvePosition);
                        if (varStartPos > this.resolvePosition || (!v2.EndPos.IsEmpty && varEndPos < this.resolvePosition))
                        {
                            continue;
                        }
                        var = v2;
                    }
//					Console.WriteLine ("var:" + var);
                    if (var == null)
                    {
                        continue;
                    }
                    IReturnType varType           = null;
                    IReturnType varTypeUnresolved = null;
                    if (var.IsQueryContinuation)
                    {
                        QueryExpression query = var.Initializer as QueryExpression;

                        QueryExpressionGroupClause grouBy = query.SelectOrGroupClause as QueryExpressionGroupClause;
                        DomLocation old = resolvePosition;
                        try {
                            resolvePosition = new DomLocation(lookupVariableLine + grouBy.Projection.StartLocation.Line,
                                                              grouBy.Projection.StartLocation.Column);
                            ResolveResult initializerResolve = visitor.Resolve(grouBy.Projection);
                            ResolveResult groupByResolve     = visitor.Resolve(grouBy.GroupBy);
                            DomReturnType resolved           = new DomReturnType(dom.GetType("System.Linq.IGrouping", new IReturnType [] {
                                DomType.GetComponentType(dom, initializerResolve.ResolvedType), groupByResolve.ResolvedType
                            }));
                            varTypeUnresolved = varType = resolved;
                        } finally {
                            resolvePosition = old;
                        }
                    }
                    else if ((var.TypeRef == null || var.TypeRef.Type == "var" || var.TypeRef.IsNull))
                    {
                        if (var.ParentLambdaExpression != null)
                        {
                            ResolveResult lambdaResolve = ResolveLambda(visitor, var.ParentLambdaExpression);
                            if (lambdaResolve != null)
                            {
                                varType           = lambdaResolve.ResolvedType;
                                varTypeUnresolved = lambdaResolve.UnresolvedType;

                                IType type = Dom.GetType(varType);
                                if (type != null && type.ClassType == MonoDevelop.Projects.Dom.ClassType.Delegate)
                                {
                                    IMethod invocationMethod = type.Methods.First();
                                    if (invocationMethod.Parameters.Count > 0)
                                    {
                                        varType = varTypeUnresolved = invocationMethod.Parameters[0].ReturnType;
                                    }
                                }
                            }
                            else
                            {
                                varType = varTypeUnresolved = DomReturnType.Void;
                            }
                        }
                        if (var.Initializer != null)
                        {
                            ResolveResult initializerResolve = visitor.Resolve(var.Initializer);
//							Console.WriteLine ("initializer : "+ var.Initializer + " result:" + initializerResolve);
                            varType           = var.IsLoopVariable ? DomType.GetComponentType(dom, initializerResolve.ResolvedType) : initializerResolve.ResolvedType;
                            varTypeUnresolved = var.IsLoopVariable ? DomType.GetComponentType(dom, initializerResolve.UnresolvedType) : initializerResolve.UnresolvedType;
//							Console.WriteLine ("resolved type:" + initializerResolve.ResolvedType + " is loop : " + var.IsLoopVariable);
//							Console.WriteLine (varType);
//							Console.WriteLine ("----------");
                        }
                    }
                    else
                    {
                        varTypeUnresolved = varType = ConvertTypeReference(var.TypeRef);
                    }
                    varType = ResolveType(varType);
                    result  = new LocalVariableResolveResult(
                        new LocalVariable(CallingMember, identifier, varType,
                                          new DomRegion(lookupVariableLine + var.StartPos.Line, var.StartPos.Column,
                                                        lookupVariableLine + var.StartPos.Line, var.EndPos.Column)),
                        var.IsLoopVariable);

                    result.ResolvedType   = varType;
                    result.UnresolvedType = varTypeUnresolved;
                    goto end;
                }
            }
            if (this.callingMember != null)
            {
                // special handling of property or field return types, they can have the same name as the return type
                // ex.: MyType MyType { get; set; }  Type1 Type1;
                if ((callingMember is IProperty || callingMember is IField) && identifier == callingMember.Name)
                {
                    int pos = editor.GetPositionFromLineColumn(resolvePosition.Line, resolvePosition.Column);
                    while (pos < editor.TextLength && !Char.IsWhiteSpace(editor.GetCharAt(pos)))
                    {
                        pos++;
                    }
                    while (pos < editor.TextLength && Char.IsWhiteSpace(editor.GetCharAt(pos)))
                    {
                        pos++;
                    }
                    StringBuilder memberName = new StringBuilder();
                    while (pos < editor.TextLength && (Char.IsLetterOrDigit(editor.GetCharAt(pos)) || editor.GetCharAt(pos) == '_'))
                    {
                        memberName.Append(editor.GetCharAt(pos));
                        pos++;
                    }
                    //Console.WriteLine ("id: '" + identifier + "' : '" + memberName.ToString () +"'" + (memberName.ToString () == identifier));
                    if (memberName.ToString() == identifier)
                    {
                        result = visitor.CreateResult(callingMember.ReturnType);
                        goto end;
                    }
                }

                if (identifier == "value" && this.callingMember is IProperty)
                {
                    result = new MemberResolveResult(this.callingMember);
                    result.UnresolvedType = ((IProperty)this.callingMember).ReturnType;
                    result.ResolvedType   = ResolveType(((IProperty)this.callingMember).ReturnType);
                    goto end;
                }
                if (this.callingMember is IMethod || this.callingMember is IProperty)
                {
                    ReadOnlyCollection <IParameter> prms = this.callingMember is IMethod
                                                ? ((IMethod)this.callingMember).Parameters
                                                : ((IProperty)this.callingMember).Parameters;
                    if (prms != null)
                    {
                        foreach (IParameter para in prms)
                        {
                            if (para.Name == identifier)
                            {
                                result = new ParameterResolveResult(para);
                                result.UnresolvedType = para.ReturnType;
                                result.ResolvedType   = ResolveType(para.ReturnType);
                                goto end;
                            }
                        }
                    }
                }
            }
            IType searchedType = SearchType(identifier);

            if (this.callingType != null && dom != null)
            {
                List <IMember> members = new List <IMember> ();
                foreach (IType type in dom.GetInheritanceTree(callingType))
                {
                    members.AddRange(type.SearchMember(identifier, true));
                }
                bool includeProtected = true;
                // filter members
                if (this.CallingMember != null)
                {
                    for (int i = 0; i < members.Count; i++)
                    {
                        if (this.CallingMember.IsStatic && !members[i].IsStatic ||
                            !members[i].IsAccessibleFrom(dom, callingType, this.CallingMember, includeProtected))
                        {
                            members.RemoveAt(i);
                            i--;
                            continue;
                        }
                    }
                }

                if (members.Count > 0)
                {
                    if (members[0] is IMethod)
                    {
                        result = new MethodResolveResult(members);
                        if (CallingMember != null)
                        {
                            result.StaticResolve = CallingMember.IsStatic;
                        }
                    }
                    else if (members[0] is IType)
                    {
                        result = new MemberResolveResult(null, true);
                        result.UnresolvedType = result.ResolvedType = new DomReturnType((IType)members[0]);
                        goto end;
                    }
                    else
                    {
                        result = new MemberResolveResult(members[0]);
                    }
                    result.UnresolvedType = members[0].ReturnType;
                    result.ResolvedType   = ResolveType(members[0].ReturnType);

                    if (members[0] is IProperty && searchedType != null && result.ResolvedType.FullName == searchedType.FullName)
                    {
                        result = new AggregatedResolveResult(result, new MemberResolveResult(null, true)
                        {
                            UnresolvedType = new DomReturnType(searchedType),
                            ResolvedType   = new DomReturnType(searchedType)
                        });
                    }
                    goto end;
                }
            }

            if (searchedType != null)
            {
                result = new MemberResolveResult(null, true);
                result.UnresolvedType = result.ResolvedType = new DomReturnType(searchedType);
                goto end;
            }

            if (dom.NamespaceExists(identifier, true))
            {
                result = new NamespaceResolveResult(identifier);
                goto end;
            }

            if (unit != null && unit.Usings != null)
            {
                foreach (IUsing u in unit.Usings)
                {
                    if (u.IsFromNamespace && u.Region.Contains(resolvePosition))
                    {
                        foreach (string ns in u.Namespaces)
                        {
                            if (dom.NamespaceExists(ns + "." + identifier, true))
                            {
                                result = new NamespaceResolveResult(ns + "." + identifier);
                                goto end;
                            }
                        }
                    }
                    foreach (KeyValuePair <string, IReturnType> alias in u.Aliases)
                    {
                        if (alias.Key == identifier || alias.Key + ".?" == identifier)
                        {
                            result = new NamespaceResolveResult(alias.Value.FullName);
                            goto end;
                        }
                    }
                }
            }
end:
            if (result != null)
            {
                result.CallingType   = CallingType;
                result.CallingMember = CallingMember;
            }
            resultTable[identifier] = result;
            return(result);
        }
        public ResolveResult Resolve(ExpressionResult expressionResult, DomLocation resolvePosition)
        {
            this.SetupResolver(resolvePosition);
            ResolveVisitor visitor = new ResolveVisitor(this);
            ResolveResult  result;

//			System.Console.WriteLine("expressionResult:" + expressionResult);

            if (unit != null && expressionResult.ExpressionContext == ExpressionContext.AttributeArguments)
            {
                string attributeName = NewCSharpExpressionFinder.FindAttributeName(editor, unit, unit.FileName);
                if (attributeName != null)
                {
                    IType type = SearchType(attributeName + "Attribute");
                    if (type == null)
                    {
                        type = SearchType(attributeName);
                    }
                    if (type != null)
                    {
                        foreach (IProperty property in type.Properties)
                        {
                            if (property.Name == expressionResult.Expression)
                            {
                                return(new MemberResolveResult(property));
                            }
                        }
                    }
                }
            }

            TypeReference typeRef;

            if (expressionResult != null && expressionResult.ExpressionContext != null && expressionResult.ExpressionContext.IsObjectCreation)
            {
                typeRef = ParseTypeReference(expressionResult);
                if (typeRef != null)
                {
                    if (dom.NamespaceExists(typeRef.Type))
                    {
//						System.Console.WriteLine("namespace resolve result");
                        result = new NamespaceResolveResult(typeRef.Type);
                    }
                    else
                    {
                        result = visitor.CreateResult(ConvertTypeReference(typeRef));
                    }
//					System.Console.WriteLine("type reference resolve result");
                    result.ResolvedExpression = expressionResult;
                    if (dom.GetType(result.ResolvedType) != null)
                    {
                        return(result);
                    }
                }
            }
            expr = ParseExpression(expressionResult);

//			System.Console.WriteLine("parsed expression:" + expr);
            if (expr == null)
            {
//				System.Console.WriteLine("Can't parse expression");
                return(null);
            }

            result = visitor.Resolve(expr);
//			if (CallingMember == null && result != null)
//				result.StaticResolve = true;
//			System.Console.WriteLine("result:" + result + "STATIC" + result.StaticResolve);
            result.ResolvedExpression = expressionResult;

            return(result);
        }