private static CodeParameterDeclarationExpression[] CreateMethodParameters(XpidlMethod xpidlMethod)
		{
			var codeParameters = new List<CodeParameterDeclarationExpression>(xpidlMethod.Parameters.Count);
			foreach (XpidlMethodParameter xpidlParameter in xpidlMethod.Parameters)
			{
				var codeParameter = new CodeParameterDeclarationExpression();

				switch (xpidlParameter.Direction)
				{
					case XpidlParameterDirection.In:
						switch (xpidlParameter.Type)
						{
							case XpidlType.nsIDRef:
							case XpidlType.nsIIDRef:
							case XpidlType.nsCIDRef:
								codeParameter.Direction = FieldDirection.Ref;
								break;
							default:
								codeParameter.Direction = FieldDirection.In;
								break;
						}
						break;
					case XpidlParameterDirection.Out:
						codeParameter.Direction = FieldDirection.Out;
						break;
					case XpidlParameterDirection.In | XpidlParameterDirection.Out:
						codeParameter.Direction = FieldDirection.Ref;
						break;
				}

				CodeAttributeDeclaration codeMarshalAsAttribute;
				CodeTypeReference parameterType = CreateCodeTypeReference(xpidlParameter.Type, out codeMarshalAsAttribute);

				if (xpidlParameter.Modifiers.Contains(XpidlParamModifier.Array))
				{
					CodeAttributeArgument marshalAsArgument = codeMarshalAsAttribute == null ? null : codeMarshalAsAttribute.Arguments[0];
					codeMarshalAsAttribute =
						new CodeAttributeDeclaration(
							new CodeTypeReference(typeof(MarshalAsAttribute)),
							new CodeAttributeArgument(
								new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(UnmanagedType)), UnmanagedType.LPArray.ToString())));
					if (marshalAsArgument != null)
					{
						marshalAsArgument.Name = "ArraySubType";
						codeMarshalAsAttribute.Arguments.Add(marshalAsArgument);
					}
					parameterType = new CodeTypeReference(parameterType, 1);
				}

				if (xpidlParameter.Modifiers.Contains(XpidlParamModifier.SizeIs) && (codeMarshalAsAttribute != null))
				{
					var sizeIsArgument =
						new CodeAttributeArgument(
							"SizeParamIndex",
							new CodePrimitiveExpression(xpidlMethod.GetParameterIndex(xpidlParameter.Modifiers[XpidlParamModifier.SizeIs])));
					codeMarshalAsAttribute.Arguments.Add(sizeIsArgument);
				}

				if (xpidlParameter.Modifiers.Contains(XpidlParamModifier.IidIs) && (codeMarshalAsAttribute == null))
				{
					codeMarshalAsAttribute =
						new CodeAttributeDeclaration(
							new CodeTypeReference(typeof(MarshalAsAttribute)),
							new CodeAttributeArgument(
								new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(UnmanagedType)), UnmanagedType.Interface.ToString())),
							new CodeAttributeArgument(
								"IidParameterIndex",
								new CodePrimitiveExpression(xpidlMethod.GetParameterIndex(xpidlParameter.Modifiers[XpidlParamModifier.IidIs]))));
					parameterType = new CodeTypeReference(typeof(Object));
				}

				codeParameter.Name = xpidlParameter.Name;
				codeParameter.Type = parameterType;
				codeParameter.CustomAttributes.AddAttribute(codeMarshalAsAttribute);

				codeParameters.Add(codeParameter);
			}
			return codeParameters.ToArray();
		}
		internal void AddNode(XpidlMethod method)
		{
			AddNodeImpl(method);
		}
		private static CodeMemberMethod CreateCodeMemberMethod(XpidlMethod xpidlMethod)
		{
			var codeMethodMember =
				new CodeMemberMethod { Name = xpidlMethod.Name.ToUpperCamel() };

			CodeParameterDeclarationExpression[] codeParameters = CreateMethodParameters(xpidlMethod);
			codeMethodMember.Parameters.AddRange(codeParameters);

			// Create CodeTypeReference and custom attributes for XpidlMethod return type
			CodeAttributeDeclaration codeMarshalAsAttribute;
			CodeTypeReference codeMethodType = CreateCodeTypeReference(xpidlMethod.Type, out codeMarshalAsAttribute);
			switch (xpidlMethod.Type)
			{
				case XpidlType.AString:
				case XpidlType.ACString:
				case XpidlType.AUTF8String:
				case XpidlType.DOMString:
					codeMethodMember.ReturnType = new CodeTypeReference(typeof(void));
					var resultParameter = new CodeParameterDeclarationExpression(codeMethodType, "result");
					resultParameter.CustomAttributes.AddAttribute(codeMarshalAsAttribute);
					codeMethodMember.Parameters.Add(resultParameter);
					break;
				default:
					codeMethodMember.ReturnType = codeMethodType;
					codeMethodMember.ReturnTypeCustomAttributes.AddAttribute(codeMarshalAsAttribute);
					break;
			}

			if ((xpidlMethod.Parameters.Count > 0) && (xpidlMethod.Parameters[xpidlMethod.Parameters.Count - 1].Modifiers.Contains(XpidlParamModifier.RetVal)))
			{
				var preserveSigAttribute = new CodeAttributeDeclaration(new CodeTypeReference(typeof(PreserveSigAttribute)));
				codeMethodMember.CustomAttributes.Add(preserveSigAttribute);
			}

			return codeMethodMember;
		}