public override SyntaxNode VisitClassDeclaration(ClassDeclarationSyntax node)
        {
            if (node.Identifier.Text == this._metadata.DtoName)
            {
                var membersList = node.Members;
                foreach (var prop in this.GenerateProperties(_metadata, ""))
                {
                    membersList = membersList.Add(prop);
                }

                var result = node.WithMembers(membersList);

                if (this._addDataContractAttrs)
                {
                    result = result.WithAttributeLists(SyntaxExtenders.CreateAttributes("DataContract"));
                }
                else
                {
                    result = result.WithAttributeLists(new SyntaxList <AttributeListSyntax>());
                }

                if (this._addDataAnnotations && this._metadata.AttributesList != null)
                {
                    result = result.AddAttributeLists(this._metadata.AttributesList.ToArray());
                }

                if (this._metadata.BaseClassDtoName != null)
                {
                    result = result.WithBaseList(this._metadata.BaseClassDtoName.ToBaseClassList());
                }

                return(result);
            }

            if (node.Identifier.Text.Contains("Mapper"))
            {
                var selectorExpressionProperty = node.Members.OfType <PropertyDeclarationSyntax>()
                                                 .Where(p => p.Identifier.ToString() == "SelectorExpression")
                                                 .FirstOrDefault();

                int insertIndex = selectorExpressionProperty == null ? 0 : node.Members.IndexOf(selectorExpressionProperty);
                var membersList = node.Members;
                foreach (var prop in _metadata.Properties.Where(p => p.IsCollection))
                {
                    var newField = SyntaxExtenders.DeclareField(type: GenerateMapperTypeName(prop.RelatedEntityName), autoCreateNew: true);
                    membersList = membersList.Insert(insertIndex++, newField);
                }

                if (this._metadata.BaseClassDtoName != null)
                {
                    var newField = SyntaxExtenders.DeclareField(type: GenerateMapperTypeName(this._metadata.BaseClassDtoName), autoCreateNew: true);
                    membersList = membersList.Insert(insertIndex++, newField);
                }

                return(base.VisitClassDeclaration(node.WithMembers(membersList)));
            }

            return(base.VisitClassDeclaration(node));
        }
        private IEnumerable <PropertyDeclarationSyntax> GenerateProperties(EntityMetadata metadata, string prefix)
        {
            foreach (var prop in metadata.Properties)
            {
                if (prop.IsRelation && !prop.IsCollection && prop.RelationMetadata != null)
                {
                    foreach (var x in GenerateProperties(prop.RelationMetadata, prefix + prop.Name))
                    {
                        yield return(x);
                    }
                }
                else if (prop.IsCollection || prop.IsSimpleProperty)
                {
                    TypeSyntax type       = null;
                    var        identifier = prefix + prop.Name;

                    if (prop.IsCollection)
                    {
                        type = (prop.RelatedEntityName + "DTO").ToCollectionType("IEnumerable");
                    }
                    else
                    {
                        type = SyntaxFactory.IdentifierName(prop.Type);
                    }

                    var result = SyntaxExtenders.DeclareAutoProperty(type, identifier);



                    if (this._addDataContractAttrs)
                    {
                        result = result.WithAttributeLists(SyntaxExtenders.CreateAttributes("DataMember"));
                    }
                    else
                    {
                        result = result.WithAttributeLists(new SyntaxList <AttributeListSyntax>());
                    }

                    if (this._addDataAnnotations && prop.AttributesList != null)
                    {
                        result = result.AddAttributeLists(prop.AttributesList.ToArray());
                    }

                    yield return(result);
                }
            }
        }
        public override SyntaxNode VisitClassDeclaration(ClassDeclarationSyntax node)
        {
            if (node.Identifier.Text == this._metadata.DtoName)
            {
                var membersList = node.Members;
                foreach (var prop in this.GenerateProperties(_metadata, ""))
                {
                    membersList = membersList.Add(prop);
                }

                var result = node.WithMembers(membersList);

                if (this._addDataContractAttrs)
                {
                    result = result.WithAttributeLists(SyntaxExtenders.CreateAttributes("DataContract"));
                }

                if (this._metadata.BaseClassDtoName != null)
                {
                    result = result.WithBaseList(this._metadata.BaseClassDtoName.ToBaseClassList());
                }

                return(result);
            }

            if (node.Identifier.Text.Contains("Mapper"))
            {
                int insertIndex = 0;
                var membersList = node.Members;
                foreach (var prop in _metadata.Properties.Where(p => p.IsCollection))
                {
                    var newField = SyntaxExtenders.DeclareField(type: GenerateMapperTypeName(prop.RelatedEntityName), autoCreateNew: true);
                    membersList = membersList.Insert(insertIndex++, newField);
                }

                if (this._metadata.BaseClassDtoName != null)
                {
                    var newField = SyntaxExtenders.DeclareField(type: GenerateMapperTypeName(this._metadata.BaseClassDtoName), autoCreateNew: true);
                    membersList = membersList.Insert(insertIndex++, newField);
                }

                return(base.VisitClassDeclaration(node.WithMembers(membersList)));
            }

            return(base.VisitClassDeclaration(node));
        }