//public static O2MethodStream map_ObjectCreateExpressions(this O2MethodStream o2MethodStream, MethodDeclaration methodDeclaration)
        public static O2MethodStream map_ObjectCreateExpressions(this O2MethodStream o2MethodStream, INode methodDeclaration)
        {
            // map ObjectCreateExpression (just about the same process as for memberReferenceExpressions
            var objectCreateExpressions = methodDeclaration.iNodes <INode, ObjectCreateExpression>();

            foreach (var objectCreateExpression in objectCreateExpressions)
            {
                var calledIMethod = o2MethodStream.O2MappedAstData.iMethod(objectCreateExpression);
                if (calledIMethod != null)
                {
                    if (o2MethodStream.O2MappedAstData.has_IMethod(calledIMethod))
                    {
                        o2MethodStream.add_IMethod(calledIMethod);
                    }
                    else
                    {
                        o2MethodStream.add_ExternalIMethod(calledIMethod);
                    }
                }
                //else
                //    "Could not resolve iMethod for ObjectCreateExpression".error();
            }

            return(o2MethodStream);
        }
        //public static O2MethodStream map_MemberReferenceExpressions(this O2MethodStream o2MethodStream, MethodDeclaration methodDeclaration)
        public static O2MethodStream map_MemberReferenceExpressions(this O2MethodStream o2MethodStream, INode methodDeclaration)
        {
            var memberReferenceExpressions = methodDeclaration.iNodes <INode, MemberReferenceExpression>();

            foreach (var memberReferenceExpression in memberReferenceExpressions)
            {
                var calledIMethod = o2MethodStream.O2MappedAstData.iMethod(memberReferenceExpression);
                if (calledIMethod != null)
                {
                    if (o2MethodStream.O2MappedAstData.has_IMethod(calledIMethod))
                    {
                        o2MethodStream.add_IMethod(calledIMethod);
                    }
                    else
                    {
                        o2MethodStream.add_ExternalIMethod(calledIMethod);
                    }
                }
                else
                {
                    o2MethodStream.map_Expression(memberReferenceExpression);
                }
                //else
                //    "Could not resolve iMethod for memberReferenceExpression".error();
            }
            return(o2MethodStream);
        }
 public static O2MethodStream add_IMethods(this O2MethodStream o2MethodStream, List <IMethod> iMethods)
 {
     foreach (var iMethod in iMethods)
     {
         o2MethodStream.add_IMethod(iMethod);
     }
     return(o2MethodStream);
 }
        public static O2MethodStream createO2MethodStream(this O2MappedAstData o2MappedAstData, IMethod iMethod, bool mapInterfacesCalls)
        {
            var o2MethodStream = new O2MethodStream(o2MappedAstData);

            o2MethodStream.add_IMethod(iMethod);
            if (mapInterfacesCalls)
            {
                o2MethodStream.resolveInterfaceCalls();
            }
            //add to O2MethodStreamCache
            O2MethodStreamCache.add(iMethod, o2MethodStream);

            return(o2MethodStream);
        }
        public static O2MethodStream map_InvocationExpressions(this O2MethodStream o2MethodStream, INode methodDeclaration)
        //public static O2MethodStream map_InvocationExpressions(this O2MethodStream o2MethodStream, MethodDeclaration methodDeclaration)
        {
            var invocationExpressions = methodDeclaration.iNodes <INode, InvocationExpression>();

            foreach (var invocationExpression in invocationExpressions)
            {
                var calledIMethod = o2MethodStream.O2MappedAstData.iMethod(invocationExpression);
                if (calledIMethod != null)
                {
                    if (o2MethodStream.O2MappedAstData.has_IMethod(calledIMethod))
                    {
                        o2MethodStream.add_IMethod(calledIMethod);
                    }
                    else
                    {
                        o2MethodStream.add_ExternalIMethod(calledIMethod);
                    }
                }
            }
            return(o2MethodStream);
        }
        public static O2MethodStream resolveInterfaceCalls(this O2MethodStream methodStream, IMethod iMethodToResolve)
        {
            var astData = methodStream.O2MappedAstData;

            try
            {
                //Action<O2MethodStream , IMethod> resolveInterfaceCalls =

                "Resolving Interface calls for: {0}".info(iMethodToResolve);
                var declaringType = iMethodToResolve.DeclaringType;
                if (declaringType.ClassType.str() == "Interface")
                {
                    "Is interface".debug();

                    foreach (var inheritedClass in astData.inheritedIClasses(declaringType))
                    {
                        var iMethods          = inheritedClass.iMethods();
                        var signatureToFind   = iMethodToResolve.fullName().remove(iMethodToResolve.Namespace);
                        var methodDeclaration = astData.methodDeclaration(iMethodToResolve);

                        foreach (var iMethod in iMethods)
                        {
                            var filteredSignature = iMethod.fullName().remove(iMethod.Namespace);
                            if (filteredSignature == signatureToFind)
                            {
                                "Adding Interface Mapping: {0} -> {1}".debug(iMethodToResolve.fullName(), iMethod.fullName());
                                if (methodStream.MappedIMethods.ContainsKey(iMethod.fullName()).isFalse())
                                {
                                    methodStream.add_IMethod(iMethod);
                                }

                                // add call to this IMethod on its interface
                                "Body: {0}".info(methodDeclaration.Body.typeName());
                                "{0} = : {1}".debug(methodDeclaration.Body.str(), (methodDeclaration.Body.str() != "[NullBlockStatement]"));
                                var body = (methodDeclaration.Body.str() != "[NullBlockStatement]")
                                                                                        ? methodDeclaration.Body
                                                                                        : methodDeclaration.add_Body();
                                var parameters = new List <IdentifierExpression>();
                                foreach (var parameter in iMethod.Parameters)
                                {
                                    parameters.Add(new IdentifierExpression(parameter.Name));
                                }
                                var tempBlockStatement = new BlockStatement();
                                var tempInvocation     = tempBlockStatement.add_Invocation(iMethod.Namespace, iMethod.name(), parameters.ToArray());
                                //make sure we don't add this more than once
                                if (body.csharpCode().contains(tempBlockStatement.csharpCode()).isFalse())
                                {
                                    "   Adding Interface Method call: {0}".info(tempBlockStatement.csharpCode().trim());
                                    body.add_Invocation(iMethod.Namespace, iMethod.name(), parameters.ToArray());
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                "[O2MethodStream.resolveInterfaceCalls]: {0}".error(ex.Message);
            }
            return(methodStream);
        }