/// <summary>
        /// Build the view types for a standard contract
        /// </summary>
        /// <param name="contractType">Type of input contract</param>
        /// <param name="component">Pipeline component the source should be added to</param>
        /// <param name="componentType">Pipeline view type (hav or AIB or generic) </param>
        /// <param name="activatable">Is this type an activatable contract</param>
        internal void BuildView(Type contractType, PipelineSegmentSource component, SegmentType componentType,bool activatable)
        {
            if (IsEvent(contractType))
            {
                //Contract type is an event contract and does not have a corresponding view
                return;
            }
            String typeName = _symbols.GetNameFromType(contractType, componentType,SegmentDirection.None,false);
            CodeCompileUnit ccu = new CodeCompileUnit();
            CodeNamespace codeNamespace = new CodeNamespace(_symbols.GetNameSpace(componentType,contractType));
            CodeTypeDeclaration type = new CodeTypeDeclaration(typeName);
            type.TypeAttributes = TypeAttributes.Abstract | TypeAttributes.Public;
            object[] typeComments = contractType.GetCustomAttributes(typeof(PipelineHints.CommentAttribute), false);
            foreach (PipelineHints.CommentAttribute comment in typeComments)
            {
                type.Comments.Add(new CodeCommentStatement(comment.Comment));

            }
            if (IsViewInterface(contractType))
            {
                type.TypeAttributes |= TypeAttributes.Interface;
            }

            //This will consult the type hierarchy we built earlier, currently we only support one base type or 1 implemented interface
            Type baseType = GetBaseContract(contractType);
            if (baseType != null)
            {
                CodeTypeReference baseRef = new CodeTypeReference(_symbols.GetNameFromType(baseType, componentType, SegmentDirection.None, contractType));
                type.BaseTypes.Add(baseRef);
            }
            if (IsEventArgs(contractType))
            {
                //Contract type is an event args type and needs it as a base
                PipelineHints.EventArgsAttribute argsType = GetEventArgs(contractType);
                if (argsType.Cancelable)
                {
                    type.BaseTypes.Add(typeof(System.ComponentModel.CancelEventArgs));
                }
                else
                {
                    type.BaseTypes.Add(typeof(EventArgs));
                }
            }
            //Only the add-in base and shared views need an attribute, the HAV doesn't need one.
            if (activatable && (componentType == SegmentType.AIB || componentType == SegmentType.VIEW))
            {
                CodeAttributeDeclaration marker = new CodeAttributeDeclaration(new CodeTypeReference(typeof(System.AddIn.Pipeline.AddInBaseAttribute)));
                type.CustomAttributes.Add(marker);
            }
            Dictionary<String, CodeMemberProperty> props = new Dictionary<string, CodeMemberProperty>();
            foreach (MethodInfo mi in GetMethodsFromContract(contractType,false))
            {
                //We only need to build the event once, so we decided to do it on event add.
                //We do not do error checking to match up adds and removes.
                if (IsEventAdd(mi))
                {

                    CodeTypeReference eventType = GetEventViewType(componentType, mi,false);
                    CodeMemberEvent abstractEvent = new CodeMemberEvent();
                    PipelineHints.EventAddAttribute attr = GetEventAdd(mi);
                    //TODO: remove this line. Abstract events are not supported by codedom since VB can't handle them.
                    abstractEvent.Attributes = MemberAttributes.Abstract;
                    abstractEvent.Name = attr.Name;
                    abstractEvent.Type = eventType;
                    type.Members.Add(abstractEvent);
                    //We only look for comments on the event add method. Any comments on the event remove method will be ignored
                    object[] eventComments = mi.GetCustomAttributes(typeof(PipelineHints.CommentAttribute), false);
                    foreach (PipelineHints.CommentAttribute comment in eventComments)
                    {
                        abstractEvent.Comments.Add(new CodeCommentStatement(comment.Comment));
                    }
                    continue;
                }
                if (IsEventRemove(mi))
                {
                    continue;
                }
                //If this method is marked as a property method using an attribute or declared directly as a property in the contrac then
                //we should express it as a property in the view, rather than as a method.
                if (IsProperty(mi))
                {
                    CodeMemberProperty prop;

                    SegmentDirection direction = SegmentDirection.None;
                    bool prefix = false;
                    prop = GetProperyDecl(contractType,type,mi,props,componentType, direction, prefix);
                    switch (GetPropertyAttribute(mi).Type)
                    {
                        case PropertyType.set:
                            prop.HasSet = true;
                            break;
                        case PropertyType.get:
                            prop.HasGet = true;
                            break;
                    }
                    object[] propComments = mi.GetCustomAttributes(typeof(PipelineHints.CommentAttribute), false);
                    foreach (PipelineHints.CommentAttribute comment in propComments)
                    {
                        prop.Comments.Add(new CodeCommentStatement(comment.Comment));
                    }
                    continue;

                }
                CodeMemberMethod method = new CodeMemberMethod();
                method.Attributes = MemberAttributes.Abstract | MemberAttributes.Public;
                method.Name = mi.Name;
                //Setup the return type for this member in the view
                method.ReturnType = GetViewTypeReference(componentType, mi.ReturnType,contractType,SegmentDirection.None);
                //For each parameter in the method in the contract, add the right one to the view
                AddParametersToViewMethod(componentType, mi, method);
                object[] methodComments = mi.GetCustomAttributes(typeof(PipelineHints.CommentAttribute), false);
                foreach (PipelineHints.CommentAttribute comment in methodComments)
                {
                    method.Comments.Add(new CodeCommentStatement(comment.Comment));
                }
                type.Members.Add(method);
            }
            codeNamespace.Types.Add(type);
            ccu.Namespaces.Add(codeNamespace);
            component.Files.Add(new SourceFile(typeName, ccu));
        }
        internal void BuildViewToContractAdapter(Type contractType, PipelineSegmentSource component,SegmentType componentType,bool activatable)
        {
            //Set up type
            String typeName = _symbols.GetNameFromType(contractType, componentType,SegmentDirection.ViewToContract,false);
            Dictionary<String, CodeMemberProperty> props = new Dictionary<string, CodeMemberProperty>();
            SegmentType viewType;
            if (componentType == SegmentType.ASA)
            {
                viewType = SegmentType.AIB;
            }
            else
            {
                viewType = SegmentType.HAV;
            }
            String viewName =  _symbols.GetNameFromType(contractType,viewType);
            //If this is an event type determine which real type this is an event on
            if (contractType.GetCustomAttributes(typeof(PipelineHints.EventHandlerAttribute), false).Length > 0)
            {
                viewName = "System.Object";
            }
            //Set up the namespace and the type declaration
            //Derive from contractbase and the specific contract
            CodeCompileUnit ccu = new CodeCompileUnit();
            CodeNamespace codeNamespace = new CodeNamespace(_symbols.GetNameSpace(componentType,contractType));
            CodeTypeDeclaration type = new CodeTypeDeclaration(typeName);
            type.TypeAttributes = TypeAttributes.Public;
            type.BaseTypes.Add(new CodeTypeReference(typeof(ContractBase)));
            type.BaseTypes.Add(new CodeTypeReference(contractType));
            //If this is activatable mark it with the addinadapterattribute
            //The viewtocontract adapter is only ever activatable in the add-in side adapter so no need to check which adapter we're in
            if (activatable)
            {
                CodeAttributeDeclaration marker = new CodeAttributeDeclaration(new CodeTypeReference(typeof(System.AddIn.Pipeline.AddInAdapterAttribute)));
                type.CustomAttributes.Add(marker);
            }
            CodeMemberField aib = new CodeMemberField(viewName, "_view");
            type.Members.Add(aib);
            //Build constructor
            //Add parameter for view type and assign it to member field _view
            CodeConstructor constructor = new CodeConstructor();
            constructor.Attributes = MemberAttributes.Public;
            CodeParameterDeclarationExpression parameter = new CodeParameterDeclarationExpression(viewName, "view");
            constructor.Parameters.Add(parameter);
            CodeAssignStatement assign = new CodeAssignStatement(new CodeVariableReferenceExpression("_view"), new CodeVariableReferenceExpression("view"));
            constructor.Statements.Add(assign);
            type.Members.Add(constructor);
            if (IsEvent(contractType))
            {
                //If this is an event type we have an additional constructor paramter that is the fieldinfo object for the eventhandler we need to invoke.
                //Add this parameter to the constructor and then store it in a member variable.
                CodeMemberField eventMember = new CodeMemberField(typeof(System.Reflection.MethodInfo), "_event");
                eventMember.Attributes |= MemberAttributes.Private;
                type.Members.Add(eventMember);
                constructor.Parameters.Add(new CodeParameterDeclarationExpression(typeof(System.Reflection.MethodInfo), "eventProp"));
                constructor.Statements.Add(new CodeAssignStatement(new CodeVariableReferenceExpression("_event"), new CodeVariableReferenceExpression("eventProp")));
                //We have already validated that this is an event so the attribute exists
                //We have also validated, while creating the views, that this contract has one method and that one method takes in one parameter
                //The one method on this type acts as the delegate with its parameter representing the event args.
                MethodInfo mi = contractType.GetMethods()[0];
                CodeExpression args = null;
                CodeTypeReference parameterType;
                ParameterInfo pi = mi.GetParameters()[0];
                parameterType = new CodeTypeReference(pi.ParameterType);

                CodeMemberMethod method = new CodeMemberMethod();
                method.Name = mi.Name;
                method.Parameters.Add(new CodeParameterDeclarationExpression(parameterType, "args"));
                method.Attributes = MemberAttributes.Public | MemberAttributes.Final;

                CodeStatementCollection adaptArgs = new CodeStatementCollection();
                //If the parameter type needs to be adapted to pass it to the contract then new up an adapter and pass that along as a parameter
                //Else simply pass the args in directly as the parameter.
                CodeTypeReference eventArgsViewType;
                if (TypeNeedsAdapting(pi.ParameterType))
                {
                    CodeObjectCreateExpression adaptedArgs = new CodeObjectCreateExpression();
                    adaptedArgs.Parameters.Add(new CodeVariableReferenceExpression("args"));
                    adaptedArgs.CreateType = new CodeTypeReference(_symbols.GetNameFromType(pi.ParameterType, componentType, SegmentDirection.ContractToView, contractType));
                    adaptedArgs.CreateType = GetViewTypeReference(viewType, pi.ParameterType, contractType, SegmentDirection.ContractToView);
                    CodeVariableDeclarationStatement adapterArgsDeclare = new CodeVariableDeclarationStatement(adaptedArgs.CreateType, "adaptedArgs");
                    CodeAssignStatement assignArgs = new CodeAssignStatement(new CodeVariableReferenceExpression("adaptedArgs"), adaptedArgs);
                    assignArgs.Right = CallStaticAdapter(componentType, pi.ParameterType, new CodeTypeReferenceExpression("args"), SegmentDirection.ContractToView);
                    adaptArgs.Add(adapterArgsDeclare);
                    adaptArgs.Add(assignArgs);
                    args = new CodeVariableReferenceExpression("adaptedArgs");
                    eventArgsViewType = new CodeTypeReference(_symbols.GetNameFromType(pi.ParameterType, viewType));
                }
                else
                {
                    args = new CodeVariableReferenceExpression("args");
                    eventArgsViewType = new CodeTypeReference(pi.ParameterType);
                }

                method.Statements.AddRange(adaptArgs);
                CodeVariableDeclarationStatement argsArray =
                    new CodeVariableDeclarationStatement(new CodeTypeReference(typeof(object[])), "argsArray");
                argsArray.InitExpression =
                    new CodeArrayCreateExpression(new CodeTypeReference(typeof(object)), new CodePrimitiveExpression(1));
                CodeAssignStatement addToArgsArray = new CodeAssignStatement();
                addToArgsArray.Left =
                    new CodeArrayIndexerExpression(new CodeVariableReferenceExpression("argsArray"),new CodePrimitiveExpression(0));
                addToArgsArray.Right = args;
                CodeMethodInvokeExpression eventInvoke = new CodeMethodInvokeExpression();
                eventInvoke.Method.MethodName = "Invoke";
                eventInvoke.Method.TargetObject = new CodeVariableReferenceExpression("_event");
                eventInvoke.Parameters.Add(new CodeVariableReferenceExpression("_view"));
                eventInvoke.Parameters.Add(new CodeVariableReferenceExpression("argsArray"));
                method.Statements.Add(argsArray);
                method.Statements.Add(addToArgsArray);
                method.Statements.Add(eventInvoke);

                //This is a cancelable event args
                //Return args.Cancel if event is hooked up
                //If event is not hooked up return false (don't cancel)
                if (mi.ReturnType.Equals(typeof(bool)))
                {
                    if (!GetEventArgs(pi.ParameterType).Cancelable)
                    {
                        throw new InvalidOperationException("Event handler method returns a bool but the event args are not cancelable:"+mi.DeclaringType.FullName + "."+mi.Name);
                    }
                    method.ReturnType = new CodeTypeReference(typeof(bool));
                    CodeFieldReferenceExpression cancel = new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("adaptedArgs"), "Cancel");
                    CodeMethodReturnStatement retCancelCheck = new CodeMethodReturnStatement(cancel);
                    method.Statements.Add(retCancelCheck);

                }

                type.Members.Add(method);
            }
            else
            {
                //For standard contract types we simply iterate through each method and build an adapter one by one
                foreach (MethodInfo mi in GetMethodsFromContract(contractType, true))
                {

                    CodeMemberMethod method = new CodeMemberMethod();
                    CodeMethodInvokeExpression cmi = new CodeMethodInvokeExpression();
                    CodeStatementCollection prologue = new CodeStatementCollection();
                    CodeStatementCollection epilogue = new CodeStatementCollection();
                    CodeMethodReturnStatement ret = new CodeMethodReturnStatement();
                    cmi.Method = new CodeMethodReferenceExpression(new CodeVariableReferenceExpression("_view"), mi.Name);
                    method.Attributes = MemberAttributes.Public;
                    method.Name = mi.Name;
                    //Set the methods return type appropriately
                    if (mi.ReturnType.Equals(typeof(void)))
                    {
                        //If return type is void return type is null and there is no return statement.
                        method.ReturnType = new CodeTypeReference(mi.ReturnType);
                        ret = null;
                    }
                    else if (!TypeNeedsAdapting(mi.ReturnType))
                    {
                        //If the return type does not need adapting return type mirrors the contract type and the return value is the direct result of the method call
                        method.ReturnType = new CodeTypeReference(mi.ReturnType);
                        ret.Expression = cmi;
                    }
                    else
                    {
                        method.ReturnType = new CodeTypeReference(mi.ReturnType);

                            //If the return type needs adapting call method, pass its return value to the static adapter, and then return that
                        CodeMethodInvokeExpression adaptExpr = CallStaticAdapter(componentType, mi.ReturnType, cmi, SegmentDirection.ViewToContract);
                        ret.Expression = adaptExpr;

                    }
                    if (IsProperty(mi))
                    {
                        method = null;

                        CodeMemberProperty myProp;

                        bool prefix = false;
                        myProp = GetProperyDecl(contractType, type, mi, props, componentType, SegmentDirection.ViewToContract, prefix);
                        CodeStatement statement = GetPropertyViewToContractAdapterImpl(componentType, viewType, mi, null);
                        switch (GetPropertyAttribute(mi).Type)
                        {
                            case PropertyType.set:
                                myProp.HasSet = true;
                                myProp.SetStatements.Add(statement);
                                break;
                            case PropertyType.get:
                                myProp.HasGet = true;
                                myProp.GetStatements.Add(statement);
                                break;
                        }

                        //If this method needs to be expressed as a property in the views we need to treat it differently.

                    }
                    else if (IsEventAdd(mi))
                    {

                        //This indicates that the method we are in really represents an event handler on the view type rather than a method
                        //We need to hook this up such that firing this event on one side causes it to fire on the other side
                        //We've already validated that these are valid setevents when building the views
                        PipelineHints.EventAddAttribute attr = GetEventAdd(mi);
                        CodeTypeReference eventArgsType = GetEventArgsType(viewType, mi, true);
                        ParameterInfo pi = mi.GetParameters()[0];
                        //Build a reference to the event handler on the view object
                        CodeEventReferenceExpression eventHandler =
                            new CodeEventReferenceExpression(new CodeVariableReferenceExpression("_view"), attr.Name);
                        //Get the adapter for the event args type
                        CodeTypeReference adapterType =
                            new CodeTypeReference(_symbols.GetNameFromType(pi.ParameterType, componentType, SegmentDirection.ContractToView, contractType));
                        CodeObjectCreateExpression adapterConstruct = new CodeObjectCreateExpression(adapterType, new CodeVariableReferenceExpression(pi.Name));
                        CodeDelegateCreateExpression handler = new CodeDelegateCreateExpression();
                        //Build the event handler
                        handler.DelegateType = new CodeTypeReference(typeof(EventHandler<>));
                        handler.DelegateType.TypeArguments.Add(eventArgsType);
                        handler.TargetObject = adapterConstruct;
                        handler.MethodName = "Handler";
                        CodeVariableDeclarationStatement handlerVar = new CodeVariableDeclarationStatement();
                        handlerVar.Type = handler.DelegateType;
                        handlerVar.Name = "adaptedHandler";
                        handlerVar.InitExpression = handler;
                        method.Statements.Add(handlerVar);
                        //Add attach the handler to the eventhandler type on the view and finish building the method
                        CodeAttachEventStatement attach = new CodeAttachEventStatement(eventHandler, new CodeVariableReferenceExpression(handlerVar.Name));
                        CodeParameterDeclarationExpression cp = new CodeParameterDeclarationExpression(pi.ParameterType, pi.Name);
                        method.Parameters.Add(cp);
                        method.Statements.Add(attach);

                        //Add Dictionary of adapters
                        CodeTypeReference dictionaryType = new CodeTypeReference("System.Collections.Generic.Dictionary");
                        dictionaryType.TypeArguments.Add(new CodeTypeReference(pi.ParameterType));
                        dictionaryType.TypeArguments.Add(handler.DelegateType);
                        CodeMemberField handlers = new CodeMemberField();
                        handlers.Name = attr.Name + "_handlers";
                        handlers.Type = dictionaryType;
                        type.Members.Add(handlers);
                        //Initialize Dictionary of Adapters;
                        CodeObjectCreateExpression createDictionary = new CodeObjectCreateExpression();
                        createDictionary.CreateType = dictionaryType;
                        CodeAssignStatement initDictionary = new CodeAssignStatement();
                        initDictionary.Left = new CodeVariableReferenceExpression(handlers.Name);
                        initDictionary.Right = createDictionary;
                        constructor.Statements.Add(initDictionary);
                        //Add current handler to the dictionary
                        CodeAssignStatement storeHandler = new CodeAssignStatement();
                        CodeArrayIndexerExpression dictLocation = new CodeArrayIndexerExpression();
                        dictLocation.TargetObject = new CodeVariableReferenceExpression(handlers.Name);
                        dictLocation.Indices.Add(new CodeVariableReferenceExpression(pi.Name));
                        storeHandler.Left = dictLocation;
                        storeHandler.Right = new CodeVariableReferenceExpression(handlerVar.Name);
                        method.Statements.Add(storeHandler);

                    }
                    else if (IsEventRemove(mi))
                    {
                        PipelineHints.EventRemoveAttribute attr = GetEventRemove(mi);
                        ParameterInfo pi = mi.GetParameters()[0];
                        //Declare the handler

                        CodeTypeReference eventArgsType = GetEventArgsType(viewType, mi, true);
                        CodeVariableDeclarationStatement handlerVar = new CodeVariableDeclarationStatement();
                        handlerVar.Name = "adaptedHandler";
                        handlerVar.Type = new CodeTypeReference(typeof(EventHandler<>));
                        handlerVar.Type.TypeArguments.Add(eventArgsType);
                        method.Statements.Add(handlerVar);
                        //TryGet handler from handlers
                        CodeMethodInvokeExpression tryGet = new CodeMethodInvokeExpression();
                        tryGet.Method.TargetObject = new CodeVariableReferenceExpression(attr.Name + "_handlers");
                        tryGet.Method.MethodName = "TryGetValue";
                        tryGet.Parameters.Add(new CodeVariableReferenceExpression(pi.Name));
                        tryGet.Parameters.Add(new CodeDirectionExpression(FieldDirection.Out, new CodeVariableReferenceExpression(handlerVar.Name)));

                        CodeConditionStatement ifGotValue = new CodeConditionStatement();
                        ifGotValue.Condition = tryGet;
                        //Remove handler
                        CodeMethodInvokeExpression removeHandler = new CodeMethodInvokeExpression();
                        removeHandler.Method.MethodName = "Remove";
                        removeHandler.Method.TargetObject = new CodeVariableReferenceExpression(attr.Name + "_handlers");
                        removeHandler.Parameters.Add(new CodeVariableReferenceExpression(pi.Name));
                        ifGotValue.TrueStatements.Add(removeHandler);
                        CodeRemoveEventStatement detach = new CodeRemoveEventStatement();
                        detach.Event = new CodeEventReferenceExpression(new CodeVariableReferenceExpression("_view"), attr.Name);
                        detach.Listener = new CodeVariableReferenceExpression(handlerVar.Name);
                        ifGotValue.TrueStatements.Add(detach);
                        method.Statements.Add(ifGotValue);
                        //Add parameters to method decl
                        CodeParameterDeclarationExpression cp = new CodeParameterDeclarationExpression(pi.ParameterType, pi.Name);
                        method.Parameters.Add(cp);
                    }
                    else
                    {
                        //This is a standard method to adapt, go through each parameter, check to see if it needs adapting.
                        //If no adapting is needed just pass on through, else find the right adapter and use it
                        foreach (ParameterInfo pi in mi.GetParameters())
                        {
                            CodeTypeReference paramViewType = GetViewTypeReference(viewType, pi.ParameterType, contractType,SegmentDirection.ViewToContract);
                            Type paramContractType = GetCannonicalContractType(pi.ParameterType);
                            if (!TypeNeedsAdapting(paramContractType))
                            {
                                CodeParameterDeclarationExpression cp = new CodeParameterDeclarationExpression(paramContractType, pi.Name);
                                CodeExpression param;
                                if (IsByRef(pi))
                                {
                                    cp.Direction = FieldDirection.Ref;
                                    param = new CodeDirectionExpression(FieldDirection.Ref, new CodeVariableReferenceExpression(pi.Name));
                                }
                                else if (IsOut(pi))
                                {
                                    cp.Direction = FieldDirection.Out;
                                    param = new CodeDirectionExpression(FieldDirection.Out, new CodeVariableReferenceExpression(pi.Name));
                                }
                                else
                                {
                                    param = new CodeVariableReferenceExpression(pi.Name);
                                }
                                method.Parameters.Add(cp);
                                cmi.Parameters.Add(param);
                            }
                            else
                            {

                                CodeParameterDeclarationExpression cp = new CodeParameterDeclarationExpression(paramContractType, pi.Name);
                                CodeMethodInvokeExpression adapterExpr =
                                    CallStaticAdapter(componentType, paramContractType, new CodeVariableReferenceExpression(pi.Name), SegmentDirection.ContractToView);
                                if (IsByRef(pi))
                                {
                                    cp.Direction = FieldDirection.Ref;
                                }
                                if (IsOut(pi))
                                {
                                    cp.Direction = FieldDirection.Out;
                                }
                                method.Parameters.Add(cp);
                                if (!IsByRef(pi) && !IsOut(pi))
                                {
                                    cmi.Parameters.Add(adapterExpr);
                                }
                                else
                                {
                                    CodeVariableDeclarationStatement var = new CodeVariableDeclarationStatement(paramViewType, pi.Name + "_view");
                                    prologue.Add(var);
                                    CodeDirectionExpression varRef;
                                    if (IsByRef(pi))
                                    {
                                        var.InitExpression = adapterExpr;
                                        varRef = new CodeDirectionExpression(FieldDirection.Ref,new CodeVariableReferenceExpression(var.Name));
                                    }
                                    else
                                    {
                                        var.InitExpression = new CodeDefaultValueExpression(var.Type);
                                        varRef = new CodeDirectionExpression(FieldDirection.Out,new CodeVariableReferenceExpression(var.Name));
                                    }
                                    CodeAssignStatement refVar = new CodeAssignStatement(
                                            new CodeVariableReferenceExpression(pi.Name),
                                            CallStaticAdapter(componentType,paramContractType,new CodeVariableReferenceExpression(var.Name),SegmentDirection.ViewToContract));
                                    cmi.Parameters.Add(varRef);
                                    epilogue.Add(refVar);
                                }
                            }
                        }
                        if (ret != null)
                        {
                            //If the previously computed return statement is not null add it to the method
                            //It already has the call to cmi's invocation so no need to add cmi again
                            method.Statements.AddRange(prologue);
                            if (epilogue.Count > 0)
                            {
                                CodeVariableDeclarationStatement retVar = new CodeVariableDeclarationStatement(mi.ReturnType, "return_variable");
                                retVar.InitExpression = ret.Expression;
                                ret = new CodeMethodReturnStatement(new CodeVariableReferenceExpression(retVar.Name));
                                method.Statements.Add(retVar);
                                method.Statements.AddRange(epilogue);
                                method.Statements.Add(ret);
                            }
                            else
                            {
                                method.Statements.Add(ret);
                            }

                        }
                        else
                        {
                            //If the previously computed return statement is null then add cmi directly to the method statements
                            method.Statements.AddRange(prologue);
                            method.Statements.Add(cmi);
                            method.Statements.AddRange(epilogue);
                        }
                    }
                    if (method != null)
                    {
                        type.Members.Add(method);
                    }
                }
            }

            //Add the method to unwrap the original view
            CodeMemberMethod unadapt = new CodeMemberMethod();
            unadapt.Name = "GetSourceView";
            unadapt.ReturnType = new CodeTypeReference(viewName);
            unadapt.Attributes = MemberAttributes.Assembly | MemberAttributes.Final;
            unadapt.Statements.Add(new CodeMethodReturnStatement(new CodeVariableReferenceExpression("_view")));
            type.Members.Add(unadapt);

            codeNamespace.Types.Add(type);
            ccu.Namespaces.Add(codeNamespace);
            component.Files.Add(new SourceFile(typeName, ccu));
        }
        internal void BuildStructView(Type contractType, PipelineSegmentSource component, SegmentType viewType)
        {
            CodeCompileUnit ccu = new CodeCompileUnit();
            CodeNamespace codeNamespace = new CodeNamespace(_symbols.GetNameSpace(viewType, contractType));
            CodeTypeDeclaration type = new CodeTypeDeclaration(_symbols.GetNameFromType(contractType, viewType, SegmentDirection.None, false));
            type.Attributes = MemberAttributes.Public;
            type.IsStruct = true;
            foreach (PropertyInfo pi in contractType.GetProperties())
            {
                CodeMemberProperty prop = new CodeMemberProperty();
                prop.Attributes = MemberAttributes.Public | MemberAttributes.Final;
                prop.Name = pi.Name;
                prop.HasGet = true;
                prop.HasSet = false;
                prop.Type = GetViewTypeReference(viewType, pi.PropertyType, contractType,SegmentDirection.None);
                prop.GetStatements.Add(
                        new CodeMethodReturnStatement(
                            new CodeVariableReferenceExpression(ConvertNameToField(pi.Name))));
                if (pi.GetSetMethod() != null)
                {
                    prop.SetStatements.Add(
                            new CodeAssignStatement(
                                new CodeVariableReferenceExpression(ConvertNameToField(pi.Name)),
                                new CodePropertySetValueReferenceExpression()));
                }
                type.Members.Add(prop);

            }
            CodeConstructor constructor = new CodeConstructor();
            constructor.Attributes = MemberAttributes.Public;
            foreach (ParameterInfo pi in contractType.GetConstructors()[0].GetParameters())
            {
                CodeParameterDeclarationExpression param = new CodeParameterDeclarationExpression();
                param.Name = pi.Name;
                param.Type = GetViewTypeReference(viewType, pi.ParameterType, contractType,SegmentDirection.None);
                constructor.Parameters.Add(param);
                CodeMemberField field = new CodeMemberField();
                field.Name = ConvertNameToField(pi.Name);
                field.Type = param.Type;
                type.Members.Add(field);
                constructor.Statements.Add(
                    new CodeAssignStatement(
                        new CodeVariableReferenceExpression(field.Name),
                        new CodeVariableReferenceExpression(pi.Name)));

            }
            type.Members.Add(constructor);

            codeNamespace.Types.Add(type);
            ccu.Namespaces.Add(codeNamespace);
            component.Files.Add(new SourceFile(type.Name, ccu));
        }
 /// <summary>
 /// This class builds the static adapters that are called directly from the adapters for other types for adapting of return values and parameters. 
 /// They are responsible for calling the constructors of the appropriate types to create the adapters and for knowing when to adapt a type and when to unwrap
 /// </summary>
 /// <param name="contractType">Type of the contract to be adapted</param>
 /// <param name="component">Component that the source should be placed in. </param>
 /// <param name="componentType">Type of component to be built: either asa or hsa</param>
 internal void BuildStaticAdapters(Type contractType, PipelineSegmentSource component, SegmentType componentType)
 {
     if (contractType.GetCustomAttributes(typeof(PipelineHints.EventHandlerAttribute), false).Length > 0)
     {
         return;
     }
     String typeName = _symbols.GetNameFromType(contractType, componentType, SegmentDirection.None, false);
     CodeCompileUnit ccu = new CodeCompileUnit();
     CodeNamespace codeNamespace = new CodeNamespace(_symbols.GetNameSpace(componentType,contractType));
     CodeTypeDeclaration type = new CodeTypeDeclaration(typeName);
     type.Attributes = MemberAttributes.Assembly | MemberAttributes.Static;
     SegmentType viewComponentType;
     if (componentType == SegmentType.ASA)
     {
         viewComponentType = SegmentType.AIB;
     }
     else if (componentType == SegmentType.HSA)
     {
         viewComponentType = SegmentType.HAV;
     }
     else
     {
         throw new InvalidOperationException("Wrong component type");
     }
     CodeTypeReference viewType = new CodeTypeReference(_symbols.GetNameFromType(contractType,viewComponentType,SegmentDirection.None,true));
     //Contract to view adapter
     CodeMemberMethod cva;
     CodeMemberMethod vca;
     cva = CreateContractToViewStaticAdapter(contractType, componentType, viewType);
     vca = CreateViewToContractStaticAdapter(contractType, componentType, viewType);
     type.Members.Add(cva);
     type.Members.Add(vca);
     codeNamespace.Types.Add(type);
     ccu.Namespaces.Add(codeNamespace);
     component.Files.Add(new SourceFile(typeName, ccu));
 }
 /// <summary>
 /// Build the view for an enum. This essentially creates a mirror image of the enum and it's values using the proper names. 
 /// </summary>
 /// <param name="contractType">Input enum type</param>
 /// <param name="component">The pipeline component this source should be part of</param>
 /// <param name="viewType">Either AIB or HAV</param>
 internal void BuildEnumView(Type contractType, PipelineSegmentSource component, SegmentType viewType)
 {
     CodeCompileUnit ccu = new CodeCompileUnit();
     CodeNamespace codeNamespace = new CodeNamespace(_symbols.GetNameSpace(viewType,contractType));
     CodeTypeDeclaration type = new CodeTypeDeclaration(_symbols.GetNameFromType(contractType,viewType,SegmentDirection.None,false));
     type.Attributes = MemberAttributes.Public;
     type.IsEnum = true;
     foreach (FieldInfo fi in contractType.GetFields())
     {
         if (!fi.Name.Equals("value__"))
         {
             CodeMemberField field = new CodeMemberField(fi.FieldType, fi.Name);
             field.InitExpression = new CodePrimitiveExpression(fi.GetRawConstantValue());
             type.Members.Add(field);
         }
     }
     if (contractType.GetCustomAttributes(typeof(FlagsAttribute), false).Length > 0)
     {
         type.CustomAttributes.Add(new CodeAttributeDeclaration("System.Flags"));
     }
     codeNamespace.Types.Add(type);
     ccu.Namespaces.Add(codeNamespace);
     component.Files.Add(new SourceFile(type.Name, ccu));
 }
        public List<PipelineSegmentSource> BuildPipeline()
        {
            //If we haven't loaded the contract assembly yet it means we want to avoid loading the contract assembly in this domain
            //and should do it remotely. Once we're in the new domain we'll have loaded the contract asm and we'll fall through this
            //and do the work.
            if (_contractAsm == null)
            {
                List<PipelineSegmentSource> source =  BuildRemotePipeline();
                return source;
            }
            _symbols = new SymbolTable(_contractAsm);
            _typeHierarchy = new Dictionary<Type, List<Type>>();
            List<PipelineSegmentSource> components = new List<PipelineSegmentSource>();
            _aib = new PipelineSegmentSource(SegmentType.AIB, _symbols);
            _asa = new PipelineSegmentSource(SegmentType.ASA, _symbols);
            _hsa = new PipelineSegmentSource(SegmentType.HSA, _symbols);
            _hav = new PipelineSegmentSource(SegmentType.HAV, _symbols);
            _view = new PipelineSegmentSource(SegmentType.VIEW, _symbols);
            components.Add(_asa);
            components.Add(_hsa);

            //If the contract assembly is marked as having the views shared we should add a generic "view" component.
            //If not then we build both add-in side and host-side view source files.
            if (ShouldShareViews())
            {
                components.Add(_view);
            }
            else
            {
                components.Add(_aib);
                components.Add(_hav);
            }
            //Parse the type hierarchy in the contract so we know how to express it in the views.
            BuildUpCastableTypeHierarchy();

            //Iterate through all of the contract types
            foreach (Type t in _contractAsm.GetExportedTypes())
            {
                //Check to see if the type is a contract
                if (typeof(IContract).IsAssignableFrom(t))
                {
                    bool activatable = false;
                    //Check to see if type is an activatable contract
                    foreach (object obj in t.GetCustomAttributes(false))
                    {
                        if (obj.GetType().Equals(typeof(System.AddIn.Pipeline.AddInContractAttribute)))
                        {
                            activatable = true;
                            break;
                        }
                    }
                    PipelineHints.PipelineSegment customSettings = PipelineHints.PipelineSegment.None;
                    if (t.GetCustomAttributes(typeof(PipelineHints.CustomPipelineAttribute), false).Length > 0)
                    {
                        customSettings = ((PipelineHints.CustomPipelineAttribute)t.GetCustomAttributes(typeof(PipelineHints.CustomPipelineAttribute), false)[0]).Segment;
                    }
                    //Build host, add-in views, and shared views
                    if ((customSettings & PipelineHints.PipelineSegment.AddInView) != PipelineHints.PipelineSegment.AddInView)
                    {
                        BuildView(t, _aib, SegmentType.AIB, activatable);
                    }
                    if ((customSettings & PipelineHints.PipelineSegment.HostView) != PipelineHints.PipelineSegment.HostView)
                    {
                        BuildView(t, _hav, SegmentType.HAV, activatable);
                    }
                    if ((customSettings & PipelineHints.PipelineSegment.Views) != PipelineHints.PipelineSegment.Views)
                    {
                        BuildView(t, _view, SegmentType.VIEW, activatable);
                    }
                    //Build add-in side adapters
                    if ((customSettings & PipelineHints.PipelineSegment.AddInSideAdapter) != PipelineHints.PipelineSegment.AddInSideAdapter)
                    {
                        BuildViewToContractAdapter(t, _asa, SegmentType.ASA, activatable);
                        BuildContractToViewAdapter(t, _asa, SegmentType.ASA, false);
                    }
                    BuildStaticAdapters(t, _asa, SegmentType.ASA);
                    //Build host side adapters
                    if ((customSettings & PipelineHints.PipelineSegment.HostSideAdapter) != PipelineHints.PipelineSegment.HostSideAdapter)
                    {
                        BuildViewToContractAdapter(t, _hsa, SegmentType.HSA, false);
                        BuildContractToViewAdapter(t, _hsa, SegmentType.HSA, activatable);
                    }
                    BuildStaticAdapters(t, _hsa, SegmentType.HSA);
                }
                else if (t.IsEnum)
                {
                    //If type is an enum build adapters and view for that
                    BuildEnumView(t, _aib, SegmentType.AIB);
                    BuildEnumView(t, _hav, SegmentType.HAV);
                    BuildEnumView(t, _view, SegmentType.VIEW);
                    BuildStaticAdapters(t, _hsa, SegmentType.HSA);
                    BuildStaticAdapters(t, _asa, SegmentType.ASA);
                    BuildStaticAdapters(t.MakeArrayType(), _hsa, SegmentType.HSA);
                    BuildStaticAdapters(t.MakeArrayType(), _asa, SegmentType.ASA);
                }
                else if (t.IsValueType)
                {
                    ValidateStructContract(t);
                    PipelineHints.PipelineSegment customSettings = PipelineHints.PipelineSegment.None;
                    if (t.GetCustomAttributes(typeof(PipelineHints.CustomPipelineAttribute), false).Length > 0)
                    {
                        customSettings = ((PipelineHints.CustomPipelineAttribute)t.GetCustomAttributes(typeof(PipelineHints.CustomPipelineAttribute), false)[0]).Segment;
                    }
                    //Build host, add-in views, and shared views
                    if ((customSettings & PipelineHints.PipelineSegment.AddInView) != PipelineHints.PipelineSegment.AddInView)
                    {
                        BuildStructView(t, _aib, SegmentType.AIB);
                    }
                    if ((customSettings & PipelineHints.PipelineSegment.HostView) != PipelineHints.PipelineSegment.HostView)
                    {
                        BuildStructView(t, _hav, SegmentType.HAV);
                    }
                    if ((customSettings & PipelineHints.PipelineSegment.Views) != PipelineHints.PipelineSegment.Views)
                    {
                        BuildStructView(t, _view, SegmentType.VIEW);
                    }
                    Type arrayVersion = t.MakeArrayType();
                    //Build add-in side adapters
                    if ((customSettings & PipelineHints.PipelineSegment.AddInSideAdapter) != PipelineHints.PipelineSegment.AddInSideAdapter)
                    {
                        BuildStaticAdapters(t, _asa, SegmentType.ASA);

                    }
                    BuildStaticAdapters(arrayVersion, _asa, SegmentType.ASA);
                    //Build host side adapters
                    if ((customSettings & PipelineHints.PipelineSegment.HostSideAdapter) != PipelineHints.PipelineSegment.HostSideAdapter)
                    {
                        BuildStaticAdapters(t, _hsa, SegmentType.HSA);
                    }
                    BuildStaticAdapters(arrayVersion, _hsa, SegmentType.HSA);

                }
            }
            return components;
        }
        internal void BuildContractToViewAdapter(Type contractType, PipelineSegmentSource component, SegmentType componentType, bool activatable)
        {
            //Set up type
            String typeName = _symbols.GetNameFromType(contractType, componentType,SegmentDirection.ContractToView,false);
            SegmentType viewType;
            if (componentType == SegmentType.ASA)
            {
                viewType = SegmentType.AIB;
            }
            else
            {
                viewType = SegmentType.HAV;
            }
            String viewName = _symbols.GetNameFromType(contractType, viewType);
            CodeCompileUnit ccu = new CodeCompileUnit();
            CodeNamespace codeNamespace = new CodeNamespace(_symbols.GetNameSpace(componentType,contractType));
            CodeTypeDeclaration type = new CodeTypeDeclaration(typeName);
            type.TypeAttributes = TypeAttributes.Public;
            type.BaseTypes.Add(new CodeTypeReference(viewName));
            if (activatable)
            {
                CodeAttributeDeclaration marker = new CodeAttributeDeclaration(new CodeTypeReference(typeof(System.AddIn.Pipeline.HostAdapterAttribute)));
                type.CustomAttributes.Add(marker);
            }
            CodeMemberField contract = new CodeMemberField(contractType, "_contract");
            CodeMemberField handle = new CodeMemberField(typeof(ContractHandle), "_handle");
            //AddDisposePattern(type, "_handle", "_contract");
            type.Members.Add(contract);
            type.Members.Add(handle);
            //Build constructor
            CodeConstructor constructor = new CodeConstructor();
            constructor.Attributes = MemberAttributes.Public;
            CodeParameterDeclarationExpression parameter = new CodeParameterDeclarationExpression(contractType, "contract");
            constructor.Parameters.Add(parameter);
            CodeAssignStatement assign = new CodeAssignStatement(new CodeVariableReferenceExpression("_contract"), new CodeVariableReferenceExpression("contract"));
            constructor.Statements.Add(assign);
            CodeObjectCreateExpression createHandle = new CodeObjectCreateExpression(typeof(ContractHandle), new CodeVariableReferenceExpression("contract"));
            assign = new CodeAssignStatement(new CodeVariableReferenceExpression("_handle"), createHandle);
            constructor.Statements.Add(assign);
            type.Members.Add(constructor);
            SegmentType viewComponentType;
            switch (componentType)
            {
                case SegmentType.ASA:
                    viewComponentType = SegmentType.AIB;
                    break;
                case SegmentType.HSA:
                    viewComponentType = SegmentType.HAV;
                    break;
                default:
                    throw new InvalidOperationException("Must be asa or hsa");
            }
            if (IsEvent(contractType))
            {
                CodeMemberMethod handler = new CodeMemberMethod();
                handler.Name = "Handler";
                handler.Attributes = MemberAttributes.Public | MemberAttributes.Final;
                CodeParameterDeclarationExpression sender = new CodeParameterDeclarationExpression(typeof(Object), "sender");
                MethodInfo mi = contractType.GetMethods()[0];

                ParameterInfo pi = mi.GetParameters()[0];
                CodeTypeReference eventArgsType = new CodeTypeReference(_symbols.GetNameFromType(pi.ParameterType, viewType, SegmentDirection.None, true));
                CodeParameterDeclarationExpression args = new CodeParameterDeclarationExpression(eventArgsType, "args");
                handler.Parameters.Add(sender);
                handler.Parameters.Add(args);
                handler.ReturnType = new CodeTypeReference(typeof(void));
                CodeMethodInvokeExpression cmi = new CodeMethodInvokeExpression();
                if (TypeNeedsAdapting(pi.ParameterType))
                {
                    CodeMethodInvokeExpression argsAdapter = CallStaticAdapter(componentType, pi.ParameterType, new CodeVariableReferenceExpression("args"), SegmentDirection.ViewToContract);
                    cmi.Parameters.Add(argsAdapter);
                }
                else
                {
                    cmi.Parameters.Add(new CodeVariableReferenceExpression("args"));
                }
                cmi.Method = new CodeMethodReferenceExpression(new CodeVariableReferenceExpression("_contract"), mi.Name);
                if (mi.ReturnType.Equals(typeof(bool)))
                {
                    CodeConditionStatement ifStatement = new CodeConditionStatement();
                    CodeAssignStatement assignCancel = new CodeAssignStatement();
                    assignCancel.Left = new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("args"), "Cancel");
                    assignCancel.Right = new CodePrimitiveExpression(true);
                    ifStatement.Condition = cmi;
                    ifStatement.TrueStatements.Add(assignCancel);
                    handler.Statements.Add(ifStatement);
                }
                else
                {
                    handler.Statements.Add(cmi);
                }
                type.Members.Add(handler);
                type.BaseTypes.Clear();
            }
            else
            {
                Dictionary<String, CodeMemberProperty> props = new Dictionary<string, CodeMemberProperty>();
                List<MethodInfo> setEvents = new List<MethodInfo>();
                foreach (MethodInfo mi in GetMethodsFromContract(contractType,true))
                {

                    CodeMethodInvokeExpression cmi = new CodeMethodInvokeExpression();
                    if (IsEventAdd(mi))
                    {
                        PipelineHints.EventAddAttribute attr = GetEventAdd(mi);
                        //Add event to list for Static Constructor Initialization
                        setEvents.Add(mi);
                        //Hook up event during constructor
                        ParameterInfo pi = mi.GetParameters()[0];
                        CodeTypeReference adapterType =
                            new CodeTypeReference(_symbols.GetNameFromType(pi.ParameterType, componentType, SegmentDirection.ViewToContract, contractType));
                        CodeObjectCreateExpression adapter = new CodeObjectCreateExpression(adapterType, new CodeThisReferenceExpression(),new CodeVariableReferenceExpression("s_" + mi.Name + "Fire"));
                        CodeMemberField handlerField = new CodeMemberField();
                        handlerField.Name = attr.Name + "_Handler";
                        handlerField.Type = adapterType;
                        type.Members.Add(handlerField);
                        CodeAssignStatement assignHandlerField = new CodeAssignStatement();
                        assignHandlerField.Left = new CodeVariableReferenceExpression(handlerField.Name);
                        assignHandlerField.Right = adapter;
                        constructor.Statements.Add(assignHandlerField);

                        //Add field
                        CodeMemberEvent eventField = new CodeMemberEvent();
                        eventField.Name = "_" + attr.Name;
                        eventField.Type = GetEventViewType(viewComponentType, mi, true);
                        type.Members.Add(eventField);

                        //Add FireMethod
                        CodeMemberMethod eventFire = new CodeMemberMethod();
                        eventFire.Attributes = MemberAttributes.Assembly;
                        eventFire.Name = "Fire" + eventField.Name;
                        eventFire.Parameters.Add(
                            new CodeParameterDeclarationExpression(eventField.Type.TypeArguments[0], "args"));
                        CodeMethodInvokeExpression eventFireInvoke = new CodeMethodInvokeExpression();
                        eventFireInvoke.Method = new CodeMethodReferenceExpression();
                        eventFireInvoke.Method.MethodName = "Invoke";
                        eventFireInvoke.Method.TargetObject = new CodeVariableReferenceExpression(eventField.Name);
                        eventFireInvoke.Parameters.Add(new CodeThisReferenceExpression());
                        eventFireInvoke.Parameters.Add(new CodeVariableReferenceExpression("args"));
                        CodeConditionStatement nullConditionalFire = new CodeConditionStatement();
                        CodeBinaryOperatorExpression eventNullCheck = new CodeBinaryOperatorExpression();
                        eventNullCheck.Left = new CodeVariableReferenceExpression(eventField.Name);
                        eventNullCheck.Right = new CodePrimitiveExpression(null);
                        eventNullCheck.Operator = CodeBinaryOperatorType.IdentityEquality;
                        nullConditionalFire.Condition = eventNullCheck;
                        nullConditionalFire.FalseStatements.Add(eventFireInvoke);
                        eventFire.Statements.Add(nullConditionalFire);
                        type.Members.Add(eventFire);

                        CodeSnippetTypeMember snippet = GetEventContractToViewFromSnippet(contractType,mi,eventField);
                        //Add override property;
                        type.Members.Add(snippet);

                        continue;
                    }
                    else if (IsEventRemove(mi))
                    {
                        continue;
                    }
                    CodeMemberMethod method = new CodeMemberMethod();
                    CodeMethodReturnStatement ret = new CodeMethodReturnStatement();
                    cmi.Method = new CodeMethodReferenceExpression(new CodeVariableReferenceExpression("_contract"), mi.Name);
                    method.Attributes = MemberAttributes.Public;
                    if (!IsViewInterface(contractType))
                    {
                        method.Attributes |= MemberAttributes.Override;
                    }
                    else
                    {
                        method.Attributes |= MemberAttributes.Final;
                    }

                    method.Name = mi.Name;

                    if (mi.ReturnType.Equals(typeof(void)))
                    {
                        method.ReturnType = new CodeTypeReference(mi.ReturnType);
                        ret = null;
                    }
                    else if (!TypeNeedsAdapting(mi.ReturnType))
                    {
                        method.ReturnType = new CodeTypeReference(mi.ReturnType);
                        ret.Expression = cmi;
                    }
                    else
                    {
                        method.ReturnType = GetViewTypeReference(viewType, mi.ReturnType, mi.DeclaringType,SegmentDirection.ContractToView);
                        ret.Expression = CallStaticAdapter(componentType, mi.ReturnType, cmi, SegmentDirection.ContractToView);
                    }
                    CodeStatementCollection prologue = new CodeStatementCollection();
                    CodeStatementCollection epilogue = new CodeStatementCollection();
                    foreach (ParameterInfo pi in mi.GetParameters())
                    {
                        CodeTypeReference paramType = GetViewTypeReference(viewType, pi.ParameterType, contractType,SegmentDirection.ContractToView);
                        if (!TypeNeedsAdapting(pi.ParameterType))
                        {
                            CodeParameterDeclarationExpression cp = new CodeParameterDeclarationExpression(paramType, pi.Name);
                            CodeExpression param;
                            if (IsByRef(pi))
                            {
                                cp.Direction = FieldDirection.Ref;
                                param = new CodeDirectionExpression(FieldDirection.Ref, new CodeVariableReferenceExpression(pi.Name));
                            }
                            else if (IsOut(pi))
                            {
                                cp.Direction = FieldDirection.Out;
                                param = new CodeDirectionExpression(FieldDirection.Out, new CodeVariableReferenceExpression(pi.Name));
                            }
                            else
                            {
                                param = new CodeVariableReferenceExpression(pi.Name);
                            }
                            method.Parameters.Add(cp);
                            cmi.Parameters.Add(param);
                        }
                        else
                        {
                            Type paramContractType = GetCannonicalContractType(pi.ParameterType);
                            CodeMethodInvokeExpression adaptExpr = CallStaticAdapter(componentType, paramContractType, new CodeVariableReferenceExpression(pi.Name), SegmentDirection.ViewToContract);
                            CodeParameterDeclarationExpression cp = new CodeParameterDeclarationExpression(paramType, pi.Name);
                            if (IsByRef(pi))
                            {
                                cp.Direction = FieldDirection.Ref;
                            }
                            if (IsOut(pi))
                            {
                                cp.Direction = FieldDirection.Out;
                            }
                            method.Parameters.Add(cp);
                            if (!IsByRef(pi) && !IsOut(pi))
                            {
                                cmi.Parameters.Add(adaptExpr);
                            }
                            else
                            {
                                CodeVariableDeclarationStatement var = new CodeVariableDeclarationStatement(paramContractType, pi.Name + "_contract");
                                prologue.Add(var);
                                CodeDirectionExpression varRef;
                                if (IsByRef(pi))
                                {
                                    var.InitExpression = adaptExpr;
                                    varRef = new CodeDirectionExpression(FieldDirection.Ref, new CodeVariableReferenceExpression(var.Name));
                                }
                                else
                                {
                                    var.InitExpression = new CodeDefaultValueExpression(var.Type);
                                    varRef = new CodeDirectionExpression(FieldDirection.Out, new CodeVariableReferenceExpression(var.Name));
                                }
                                CodeAssignStatement refVar = new CodeAssignStatement(
                                    new CodeVariableReferenceExpression(pi.Name),
                                    CallStaticAdapter(componentType, paramContractType, new CodeVariableReferenceExpression(var.Name), SegmentDirection.ContractToView));
                                cmi.Parameters.Add(varRef);
                                epilogue.Add(refVar);
                            }
                        }
                    }
                    if (IsProperty(mi))
                    {
                        CodeMemberProperty myProp = GetProperyDecl(contractType, type, mi, props, viewComponentType, SegmentDirection.ContractToView, true);
                        CodeStatement statement = GetPropertyContractToViewAdapterImpl(componentType, viewType, mi, null);
                        switch (GetPropertyAttribute(mi).Type)
                        {
                            case PropertyType.set:
                                myProp.HasSet = true;
                                myProp.SetStatements.Add(statement);
                                break;
                            case PropertyType.get:
                                myProp.HasGet = true;
                                myProp.GetStatements.Add(statement);
                                break;
                        }
                    }
                    else
                    {
                        if (ret != null)
                        {
                            method.Statements.AddRange(prologue);
                            if (epilogue.Count > 0)
                            {
                                CodeVariableDeclarationStatement retVar = new CodeVariableDeclarationStatement(GetViewTypeReference(viewType, mi.ReturnType, mi.DeclaringType,SegmentDirection.ViewToContract), "return_variable");
                                retVar.InitExpression = ret.Expression;
                                ret = new CodeMethodReturnStatement(new CodeVariableReferenceExpression(retVar.Name));
                                method.Statements.Add(retVar);
                                method.Statements.AddRange(epilogue);
                                method.Statements.Add(ret);
                            }
                            else
                            {
                                method.Statements.Add(ret);
                            }
                        }
                        else
                        {
                            method.Statements.AddRange(prologue);
                            method.Statements.Add(cmi);
                            method.Statements.AddRange(epilogue);
                        }

                        type.Members.Add(method);
                    }
                }
                ProcessSetEvents(viewName, type, setEvents);

            }
            CodeMemberMethod unadapt = new CodeMemberMethod();
            unadapt.Name = "GetSourceContract";
            unadapt.ReturnType = new CodeTypeReference(contractType);
            unadapt.Attributes = MemberAttributes.Assembly | MemberAttributes.Final;
            unadapt.Statements.Add(new CodeMethodReturnStatement(new CodeVariableReferenceExpression("_contract")));
            type.Members.Add(unadapt);

            codeNamespace.Types.Add(type);
            ccu.Namespaces.Add(codeNamespace);
            component.Files.Add(new SourceFile(typeName,ccu));
        }