/// <summary>
        /// Creates a method that parses an XML element returned from the API by setting creating an instance
        /// of the given class and setting its properties.
        /// </summary>
        private MethodDeclarationSyntax GenerateParseMethod(string className, IEnumerable <Property> properties)
        {
            var elementParameter = SyntaxEx.Parameter("XElement", "element");
            var wikiParameter    = SyntaxEx.Parameter("WikiInfo", "wiki");
            var statements       = new List <StatementSyntax>();

            var resultLocal = SyntaxEx.LocalDeclaration("var", "result", SyntaxEx.ObjectCreation(className));

            statements.Add(resultLocal);

            foreach (var property in properties)
            {
                ExpressionSyntax propertyValueAccess;
                bool             checkForNull;

                if (property.Name == "*")
                {
                    propertyValueAccess = (NamedNode)elementParameter;
                    checkForNull        = false;
                }
                else
                {
                    propertyValueAccess = SyntaxEx.Invocation(
                        SyntaxEx.MemberAccess(elementParameter, "Attribute"), SyntaxEx.Literal(property.Name));
                    checkForNull = true;
                }
                var propertyValueLocal = SyntaxEx.LocalDeclaration(
                    "var", GetPropertyName(property.Name, false) + "Value", propertyValueAccess);

                statements.Add(propertyValueLocal);

                var valueValue = SyntaxEx.MemberAccess(propertyValueLocal, "Value");

                var assignment = SyntaxEx.Assignment(
                    SyntaxEx.MemberAccess(resultLocal, GetPropertyName(property.Name)),
                    Wiki.TypeManager.CreateConverter(
                        property, ClassNameBase, valueValue,
                        (NamedNode)wikiParameter));

                if (checkForNull)
                {
                    ExpressionSyntax condition = SyntaxEx.NotEquals((NamedNode)propertyValueLocal, SyntaxEx.NullLiteral());

                    var simpleType = property.Type as SimpleParameterType;
                    if (simpleType == null || (simpleType.Name != "string" && simpleType.Name != "boolean"))
                    {
                        condition = SyntaxEx.And(
                            condition, SyntaxEx.NotEquals(valueValue, SyntaxEx.Literal("")));
                    }

                    var ifStatement = SyntaxEx.If(condition, assignment);
                    statements.Add(ifStatement);
                }
                else
                {
                    statements.Add(assignment);
                }
            }

            statements.Add(SyntaxEx.Return(resultLocal));

            return(SyntaxEx.MethodDeclaration(
                       new[] { SyntaxKind.PublicKeyword, SyntaxKind.StaticKeyword }, className, "Parse",
                       new[] { elementParameter, wikiParameter }, statements));
        }
        /// <summary>
        /// Creates an entry method, that is used to execute query for normal modules
        /// or that can be used as a base for a query for query modules.
        /// </summary>
        protected void GenerateMethod(
            Module module, IEnumerable <Parameter> methodParameters, string resultClassName,
            FieldDeclarationSyntax propsField, string fileName, bool nullableParameters, SortType?sortType)
        {
            var propertiesField = CreatePropertiesField(module, resultClassName, propsField, sortType);

            ExpressionSyntax queryParameters = SyntaxEx.Invocation(
                SyntaxEx.MemberAccess("QueryParameters", SyntaxEx.GenericName("Create", resultClassName)));

            var queryParametersLocal = SyntaxEx.LocalDeclaration("var", "queryParameters", queryParameters);

            var documentationElements = new List <XmlElementSyntax>();

            var summary = SyntaxEx.DocumentationSummary(module.Description);

            documentationElements.Add(summary);

            var parameters = new List <ParameterSyntax>();
            IList <StatementSyntax> statements = new List <StatementSyntax>();

            statements.Add(queryParametersLocal);

            methodParameters = methodParameters
                               .Where(p => !p.Deprecated)
                               .Where(p => p.Name != "continue")
                               .OrderByDescending(p => p.Required);

            foreach (var methodParameter in methodParameters)
            {
                var nullable      = nullableParameters && !methodParameter.Required;
                var typeName      = Wiki.TypeManager.GetTypeName(methodParameter, ClassNameBase, nullable, false);
                var parameterName = GetPropertyName(methodParameter.Name);

                // this type cannot be processed
                if (typeName == null)
                {
                    continue;
                }

                var parameter = SyntaxEx.Parameter(typeName, parameterName, nullable ? SyntaxEx.NullLiteral() : null);

                parameters.Add(parameter);

                ExpressionSyntax valueExpression = (NamedNode)parameter;

                if (nullable && typeName.EndsWith("?"))
                {
                    valueExpression = SyntaxEx.MemberAccess(valueExpression, "Value");
                }

                ExpressionSyntax newQueryParameters;
                if (typeName == "System.IO.Stream")
                {
                    newQueryParameters = SyntaxEx.Invocation(
                        SyntaxEx.MemberAccess(queryParametersLocal, "AddFile"),
                        SyntaxEx.Literal(methodParameter.Name),
                        valueExpression);
                }
                else
                {
                    newQueryParameters = SyntaxEx.Invocation(
                        SyntaxEx.MemberAccess(queryParametersLocal, "AddSingleValue"),
                        SyntaxEx.Literal(methodParameter.Name),
                        SyntaxEx.Invocation(SyntaxEx.MemberAccess(valueExpression, "ToQueryString")));
                }
                var queryParametersAssignment = SyntaxEx.Assignment(queryParametersLocal, newQueryParameters);

                if (nullable)
                {
                    var assignmentWithCheck = SyntaxEx.If(
                        SyntaxEx.NotEquals((NamedNode)parameter, SyntaxEx.NullLiteral()), queryParametersAssignment);

                    statements.Add(assignmentWithCheck);
                }
                else
                {
                    statements.Add(queryParametersAssignment);
                }

                var parameterDocumentation = SyntaxEx.DocumentationParameter(parameterName, methodParameter.Description);

                documentationElements.Add(parameterDocumentation);
            }

            statements = GenerateMethodBody(
                SyntaxEx.ObjectCreation(
                    SyntaxEx.GenericName("QueryProcessor", resultClassName),
                    SyntaxFactory.IdentifierName("m_wiki"),
                    (NamedNode)propertiesField), (NamedNode)queryParametersLocal, statements);

            var modifiers = new List <SyntaxKind> {
                SyntaxKind.PublicKeyword
            };

            if (statements == null)
            {
                modifiers.Add(SyntaxKind.AbstractKeyword);
            }

            var method = SyntaxEx.MethodDeclaration(
                modifiers, GenerateMethodResultType(), ClassNameBase, parameters, statements)
                         .WithLeadingTrivia(SyntaxFactory.Trivia(SyntaxEx.DocumentationComment(documentationElements)));

            AddMembersToClass(fileName, propertiesField, method);
        }