internal EnvDTE.CodeParameter AddParameter(EnvDTE.CodeElement parent, SyntaxNode containerNode, string name, object type, object position)
        {
            var typeSymbol = CodeModelService.GetTypeSymbol(type, this.GetSemanticModel(), containerNode.SpanStart);
            var typeName   = typeSymbol.GetEscapedFullName();

            var parameterNode  = CodeModelService.CreateParameterNode(CodeModelService.GetUnescapedName(name), typeName);
            var insertionIndex = CodeModelService.PositionVariantToParameterInsertionIndex(position, containerNode, fileCodeModel: this);

            var newNode = InsertParameter(containerNode, parameterNode, insertionIndex);

            // Since parameters form part of the NodeKey for functions, delegates, and indexers,
            // creating a CodeParameter hooked up to the correct parent is a little tricky. After
            // the call to InsertParameter, the syntax tree has been updated, but not the NodeKey
            // map or the NodeKey in the parent CodeParameter. If we delegate the creation of the
            // CodeParameter to CodeModelService.CreateInternalCodeElement, it will attempt to
            // look up an element in the NodeKey map based on the new syntax tree. This will fail,
            // causing it to create a new, duplicate element for the parent. Later, when we
            // reacquire the NodeKeys, the original element will get the proper NodeKey, while the
            // duplicate will be updated to a meaningless NodeKey. Since the duplicate is the one
            // being used by the CodeParameter, most operations on it will then fail.
            // Instead, we need to have the parent passed in to us.
            var parentObj = ComAggregate.GetManagedObject <AbstractCodeMember>(parent);

            return(CodeParameter.Create(this.State, parentObj, CodeModelService.GetParameterName(newNode)));
        }