private CodeExpression CreateFunctionParameter(CodeMemberMethod method, UniqueIdentifierService uniqueIdentifierService, FunctionParameter parameter)
        {
            // get (adjusted) name of parameter
            string adjustedParameterName;
            if (!uniqueIdentifierService.TryGetAdjustedName(parameter, out adjustedParameterName))
            {
                Debug.Fail("parameter must be registered in identifier service");
            }
            Type parameterType = DetermineParameterType(parameter);

            // make sure the variable name does not collide with any parameters to the method, or any
            // existing variables (all registered in the service)
            string variableName = uniqueIdentifierService.AdjustIdentifier(parameter.Name + "Parameter");

            // ObjectParameter variableName;
            // if (null != parameterName)
            // {
            //     variableName = new ObjectParameter("parameterName", adjustedParameterName);
            // }
            // else
            // {
            //     variableName = new ObjectParameter("parameterName", typeof(parameterType));
            // }
            method.Statements.Add(
                new CodeVariableDeclarationStatement(TypeReference.ForType(typeof(ObjectParameter)), variableName));
            CodeExpression variableReference = new CodeVariableReferenceExpression(variableName);
            CodeExpression parameterReference = new CodeVariableReferenceExpression(adjustedParameterName);
            CodeStatement nullConstructor = new CodeAssignStatement(variableReference,
                new CodeObjectCreateExpression(TypeReference.ForType(typeof(ObjectParameter)),
                new CodePrimitiveExpression(parameter.Name),
                new CodeTypeOfExpression(TypeReference.ForType(parameterType))));
            CodeStatement valueConstructor = new CodeAssignStatement(variableReference,
                new CodeObjectCreateExpression(TypeReference.ForType(typeof(ObjectParameter)),
                new CodePrimitiveExpression(parameter.Name),
                parameterReference));
            CodeExpression notNullCondition;
            if (parameterType.IsValueType)
            {
                // Value type parameters generate Nullable<ValueType> arguments (see CreateFunctionArgument).
                // We call Nullable<ValueType>.HasValue to determine whether the argument passed in is null
                // (since null != nullableTypeInstance does not work in VB)
                //
                // parameterReference.HasValue
                notNullCondition = new CodePropertyReferenceExpression(
                    parameterReference,
                    "HasValue");
            }
            else
            {
                // use parameterReference != null
                notNullCondition = new CodeBinaryOperatorExpression(
                    parameterReference,
                    CodeBinaryOperatorType.IdentityInequality,
                    NullExpression);
            }
            method.Statements.Add(
                new CodeConditionStatement(
                    notNullCondition,
                    new CodeStatement[] { valueConstructor, },
                    new CodeStatement[] { nullConstructor, }
                )
            );
            return variableReference;
        }
        /// <summary>
        /// Create a method entry point for a function import yielding an entity reader.
        /// </summary>
        /// <param name="functionImport">SOM for function import; must not be null and must yield
        /// an entity reader.</param>
        /// <returns>Method definition.</returns>
        private CodeMemberMethod CreateFunctionImportStructuralTypeReaderMethod(EdmFunction functionImport)
        {
            // Trying to get:
            //
            ///// <summary>
            ///// Documentation
            ///// </summary>
            //public ObjectQueryResult<MyType> MyFunctionImport(Nullable<int> id, string foo)
            //{
            //    ObjectParameter idParameter;
            //    if (id.HasValue)
            //    {
            //        idParameter = new ObjectParameter("id", id);
            //    }
            //    else
            //    {
            //        idParameter = new ObjectParameter("id", typeof(int));
            //    }
            //    ObjectParameter fooParameter;
            //    if (null != foo)
            //    {
            //        fooParameter = new ObjectParameter("foo", foo);
            //    }
            //    else
            //    {
            //        fooParameter = new ObjectParameter("foo", typeof(string));
            //    }
            //    return base.ExecuteFunction<MyType>("MyFunctionImport", idParameter, fooParameter);
            //}
            Debug.Assert(null != functionImport);

            CodeMemberMethod method = new CodeMemberMethod();
            Generator.AttributeEmitter.EmitGeneratedCodeAttribute(method);
            method.Name = functionImport.Name;
            method.Attributes = GetFunctionImportAccessibility(functionImport) | MemberAttributes.Final;

            UniqueIdentifierService uniqueIdentifierService = new UniqueIdentifierService(
                this.Generator.IsLanguageCaseSensitive, 
                s => Utils.FixParameterName(s));

            // determine element return type
            EdmType returnType = GetReturnTypeFromFunctionImport(functionImport);
            if (Helper.IsCollectionType(returnType))
            {
                // get the type in the collection
                returnType = ((CollectionType)returnType).TypeUsage.EdmType;
            }
            CodeTypeReference elementType = Generator.GetLeastPossibleQualifiedTypeReference(returnType);
            method.ReturnType = TypeReference.ObjectResult(elementType);

            // generate <summary> comments based on CSDL Documentation element
            CommentEmitter.EmitSummaryComments(functionImport, method.Comments);

            // build up list of arguments to ExecuteFunction
            List<CodeExpression> executeArguments = new List<CodeExpression>();
            executeArguments.Add(new CodePrimitiveExpression(functionImport.Name)); // first argument is the name of the function
            foreach (FunctionParameter parameter in functionImport.Parameters)
            {
                CreateFunctionArgument(method, uniqueIdentifierService, parameter);
            }

            // add fields representing object parameters
            foreach (FunctionParameter parameter in functionImport.Parameters)
            {
                if (parameter.Mode == ParameterMode.In)
                {
                    CodeExpression variableReference = CreateFunctionParameter(method, uniqueIdentifierService, parameter);
                    executeArguments.Add(variableReference);
                }
                else
                {
                    // the parameter is already being passed in as an argument; just remember it and 
                    // pass it in as an argument
                    string adjustedParameterName;
                    if (!uniqueIdentifierService.TryGetAdjustedName(parameter, out adjustedParameterName))
                    {
                        Debug.Fail("parameter must be registered in identifier service");
                    }
                    executeArguments.Add(new CodeVariableReferenceExpression(adjustedParameterName));
                }
            }

            // Add call to ExecuteFunction
            //      return ExecuteFunction<elementType>("FunctionImportName", { object parameters });
            CodeMethodReferenceExpression executeFunctionMethod = new CodeMethodReferenceExpression(
                new CodeBaseReferenceExpression(),
                "ExecuteFunction",
                new CodeTypeReference[] { elementType });
            method.Statements.Add(
                new CodeMethodReturnStatement(
                    new CodeMethodInvokeExpression(executeFunctionMethod, executeArguments.ToArray())
                )
            );

            // invoke the ExecuteFunction method passing in parameters
            return method;
        }