private static IEnumerable <string> GetOwnerNamesList(IClassDeclaration classDeclaration)
        {
            var ownerNamespace = classDeclaration.GetContainingNamespaceDeclaration();

            while (ownerNamespace != null)
            {
                yield return(ownerNamespace.ShortName);

                var namespaceQualification = ownerNamespace.NamespaceQualification;
                if (namespaceQualification != null)
                {
                    var qualifier = namespaceQualification.Qualifier;
                    while (qualifier != null)
                    {
                        yield return(qualifier.ShortName);

                        qualifier = qualifier.Qualifier;
                    }
                }
                ownerNamespace = ownerNamespace.GetContainingNamespaceDeclaration();
            }
        }
        /// <summary>
        /// Adds the interface.
        /// </summary>
        /// <param name="classDeclaration">
        /// The class declaration.
        /// </param>
        /// <param name="factory">
        /// The factory.
        /// </param>
        private static void AddProxyClass(IClassDeclaration classDeclaration, CSharpElementFactory factory)
        {
            var className = classDeclaration.DeclaredName;
              var variableName = GetVariableName(classDeclaration);

              var namingPolicy = CodeStyleSettingsManager.Instance.CodeStyleSettings.GetNamingSettings2().PredefinedNamingRules[NamedElementKinds.PrivateInstanceFields];
              var prefix = namingPolicy.NamingRule.Prefix;

              var proxyProperty = prefix + variableName;

              var isStatic = false; // classDeclaration.IsStatic;

              var staticClass = isStatic ? " static" : string.Empty;

              var code = new StringBuilder(string.Format("public{1} class {0}Proxy {{", classDeclaration.DeclaredName, staticClass));

              if (!isStatic)
              {
            code.Append(string.Format("\r\nreadonly {0} {1};", classDeclaration.DeclaredName, proxyProperty));
            code.Append(string.Format("public {0}Proxy({0} {1}) {{\r\n{2} = {1};\r\n}}\r\n", classDeclaration.DeclaredName, variableName, proxyProperty));
              }

              var cls = classDeclaration.DeclaredElement as IClass;
              if (cls == null)
              {
            return;
              }

              AddMembers(code, cls, proxyProperty, className);

              code.Append("}");

              var memberDeclaration = factory.CreateTypeMemberDeclaration(code.ToString()) as IClassDeclaration;

              var namespaceDeclaration = classDeclaration.GetContainingNamespaceDeclaration();

              namespaceDeclaration.AddTypeDeclarationAfter(memberDeclaration, classDeclaration);
        }
        private static void AddProxyClass(IClassDeclaration classDeclaration, CSharpElementFactory factory)
        {
            var builderType = string.Format("{0}Builder", classDeclaration.DeclaredName);

            var code = new StringBuilder(string.Format("public class {0} {{", builderType));

            code.AppendLine();
            var cls = classDeclaration.DeclaredElement as IClass;

            if (cls == null)
            {
                return;
            }

            var ctor = cls.Constructors.OrderByDescending(x => x.Parameters.Count).FirstOrDefault();

            if (ctor == null)
            {
                return;
            }

            var fields  = new StringBuilder();
            var methods = new StringBuilder();

            foreach (var parameter in ctor.Parameters)
            {
                var typePresentableName  = parameter.Type.GetPresentableName(cls.PresentationLanguage);
                var shortName            = parameter.ShortName;
                var capitalizedShortName = shortName.Capitalize();

                fields.AppendLine("private {0} _{1};", typePresentableName, shortName);
                methods.AppendLine("public {2} With{1}({0} value){{ ", typePresentableName, capitalizedShortName, builderType);
                methods.AppendLine(" _{0} = value;", shortName);
                methods.AppendLine("return this;");
                methods.AppendLine("}");
                methods.AppendLine();

                if (parameter.Type.IsGenericIEnumerable())
                {
                    var genericParameter = typePresentableName.Split(new[] { '<', '>' })[1];
                    var listType         = string.Format("List<{0}>", genericParameter);
                    var singularName     = NounUtil.GetSingular(capitalizedShortName);

                    methods.AppendLine("public {0} Add{1}({2} value){{", builderType, singularName, genericParameter);
                    methods.AppendLine(" if(_{0} == null){{", shortName);
                    methods.AppendLine("  _{0} = new {1}();", shortName, listType);
                    methods.AppendLine(" }");
                    methods.AppendLine("  var collection = _{0} as ICollection<{1}>;", shortName, genericParameter);
                    methods.AppendLine("  if (collection == null || collection.IsReadOnly){");
                    methods.AppendLine("     throw new InvalidOperationException(\"Add{0}() method cannot be used with this collection type\");", singularName);
                    methods.AppendLine("  }");
                    methods.AppendLine(" collection.Add(value);");
                    methods.AppendLine(" return this;");
                    methods.AppendLine("}");
                    methods.AppendLine();
                }
            }

            code.Append(fields);
            code.Append(methods);


            code.AppendLine("public {0} Build(){{", classDeclaration.DeclaredName);
            code.AppendFormat("return new  {0}(", classDeclaration.DeclaredName);
            code.Append(ctor.Parameters.Select(x => string.Format("_{0}", x.ShortName)).ToArray().Join(", "));
            code.AppendLine(");");
            code.AppendLine("}");


            code.Append("}");

            var memberDeclaration = factory.CreateTypeMemberDeclaration(code.ToString()) as IClassDeclaration;

            var namespaceDeclaration = classDeclaration.GetContainingNamespaceDeclaration();

            namespaceDeclaration.AddTypeDeclarationAfter(memberDeclaration, classDeclaration);
        }