private void WriteEntityServiceContract(IEntity entity)
        {
            cw.WriteLine("[ServiceContract]");
            cw.WriteLine("public interface {0}", NamingHelperWCF.GetEntityServiceName(entity));
            cw.BeginScope();
            cw.WriteLine("[OperationContract]");
            cw.WriteLine("{0} {1};",
                         NamingHelper.ToDTOTypeName(entity, environment),
                         NamingHelperWCF.MethodSignature_Create(entity));

            cw.WriteLine("[OperationContract]");
            cw.WriteLine("{0} {1};",
                         NamingHelper.ToDTOTypeName(entity, environment),
                         ServicesLayerConfig.Methods.GetProxyById(entity.Constraints.PrimaryId, environment).Signature);

            foreach (IUniqueId uid in entity.Constraints.UniqueIds)
            {
                cw.WriteLine("[OperationContract]");
                cw.WriteLine("{0} {1};",
                             NamingHelper.ToDTOTypeName(entity, environment),
                             ServicesLayerConfig.Methods.GetProxyByUniqueId(uid, environment).Signature);
            }

            cw.EndScope();
            cw.WriteLine();
        }
        protected override void Write()
        {
            cw.WriteUsing("System.ServiceModel");
            cw.WriteUsing("System.ServiceModel.Description");
            cw.WriteLine();

            ns.BeginScope(ServicesLayerConfig.ServicesNamespace);

            cw.WriteLine("[ServiceContract]");
            cw.WriteLine("public interface {0}", NamingHelperWCF.IntfName_PersistenceService);
            cw.BeginScope();
            cw.WriteLine("[OperationContract]");
            cw.WriteLine("{0} {1};",
                         NamingHelper.ToDTOTypeName(NamingHelper.ClassName_UnitOfWorkDTO),
                         NamingHelperWCF.MethodSignature_Create(NamingHelper.ClassName_UnitOfWorkDTO));
            cw.WriteLine("[OperationContract]");
            cw.WriteLine("CommitResult Commit({0} {1});",
                         NamingHelper.ToDTOTypeName(NamingHelper.ClassName_UnitOfWorkDTO),
                         NamingHelper.VarName_UnitOfWork);
            cw.EndScope();
            cw.WriteLine();

            foreach (IEntity entity in Model.Entities)
            {
                WriteEntityServiceContract(entity);
            }

            ns.EndScope();
        }
        protected override void Write()
        {
            cw.WriteUsing("System.Runtime.Serialization");
            cw.WriteUsing("System.Collections.Generic");
            cw.WriteUsing("System.Text");
            cw.WriteUsing("System.ServiceModel");
            cw.WriteUsing("System.ServiceModel.Description");
            cw.WriteLine();

            ns.BeginScope(ServicesLayerConfig.ServicesNamespace);

            cw.WriteLine("[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]");
            cw.WriteLine("public partial class {0} :", ClassName_DomainServices);
            cw.Indent++;
            cw.WriteLine("{0},", NamingHelperWCF.IntfName_PersistenceService);
            int count = 1;

            foreach (IEntity entity in Model.Entities)
            {
                cw.WriteLine("{0}{1}",
                             NamingHelperWCF.GetEntityServiceName(entity),
                             count == Model.Entities.Count ? "" : ",");
                count++;
            }
            cw.Indent--;
            cw.BeginScope();

            cw.BeginRegion(NamingHelperWCF.IntfName_PersistenceService);
            cw.WriteLine("{0} {1}.{2}",
                         NamingHelper.ToDTOTypeName(NamingHelper.ClassName_UnitOfWorkDTO),
                         NamingHelperWCF.IntfName_PersistenceService,
                         NamingHelperWCF.MethodSignature_Create(NamingHelper.ClassName_UnitOfWorkDTO));
            cw.BeginScope();
            cw.WriteLine("return new {0}();", NamingHelper.ToDTOTypeName(NamingHelper.ClassName_UnitOfWorkDTO));
            cw.EndScope();
            cw.WriteLine();
            cw.WriteLine("CommitResult {0}.Commit({1} {2})",
                         NamingHelperWCF.IntfName_PersistenceService,
                         NamingHelper.ToDTOTypeName(NamingHelper.ClassName_UnitOfWorkDTO),
                         NamingHelper.VarName_UnitOfWork);
            cw.BeginScope();
            cw.WriteLine("return {0}.Commit();", NamingHelper.VarName_UnitOfWork);
            cw.EndScope();
            cw.EndRegion();
            cw.WriteLine();

            foreach (IEntity entity in Model.Entities)
            {
                WriteEntityService(entity);
            }

            cw.EndScope();
            ns.EndScope();
        }
        protected override void Write()
        {
            cw.WriteUsing("System.ServiceModel");
            cw.WriteUsing("System.ServiceModel.Description");
            cw.WriteUsing("System.ServiceModel.Channels");
            cw.WriteLine();

            ns.BeginScope(ServicesLayerConfig.ServicesNamespace);
            cw.BeginComment();
            cw.WriteLine("How to setup security: http://msdn.microsoft.com/en-us/library/ms733768.aspx");
            cw.WriteLine("If you are running on Windows Vista, Windows Server 2008 R2 or Windows 7, use the Netsh.exe tool");
            cw.WriteLine("Example: netsh http add urlacl url=http://+:8080/MyUri user=DOMAIN\\user");
            cw.EndComment();

            cw.BeginClass(AccessLevel.Public, false, ClassName_ServicesHost, null);
            cw.WriteLine("private ServiceHost host;");
            cw.WriteLine();
            cw.WriteLine("public void Start()");
            cw.BeginScope();
            cw.WriteLine("host = new ServiceHost(typeof(DomainServices));");
            cw.WriteLine("Console.WriteLine(\"Service started at: {0}\", host.BaseAddresses[0]);");
            cw.WriteLine("WSHttpBinding binding = new WSHttpBinding();");
            cw.WriteLine("host.AddServiceEndpoint(typeof({0}), binding, \"\");",
                         NamingHelperWCF.IntfName_PersistenceService);
            foreach (IEntity entity in Model.Entities)
            {
                cw.WriteLine("host.AddServiceEndpoint(typeof({0}), binding, \"\");",
                             NamingHelperWCF.GetEntityServiceName(entity));
            }
            cw.WriteLine("host.Open();");
            cw.WriteLine("Console.WriteLine(\"The service is ready\");");
            cw.EndScope();
            cw.WriteLine();

            cw.WriteLine("public void Stop()");
            cw.BeginScope();
            cw.WriteLine("host.Close();");
            cw.WriteLine("Console.WriteLine(\"The service is down\");");
            cw.EndScope();

            cw.EndClass();

            ns.EndScope();
        }
        private void WriteEntityService(IEntity entity)
        {
            cw.BeginRegion(NamingHelperWCF.GetEntityServiceName(entity));
            // Create
            cw.WriteLine("{0} {1}.{2}",
                         NamingHelper.ToDTOTypeName(entity, environment),
                         NamingHelperWCF.GetEntityServiceName(entity),
                         NamingHelperWCF.MethodSignature_Create(entity));
            cw.BeginScope();
            cw.WriteLine("return new {0}();", NamingHelper.ToDTOTypeName(entity, environment));
            cw.EndScope();
            cw.WriteLine();

            // GetById
            cw.WriteLine("{0} {1}.{2}",
                         NamingHelper.ToDTOTypeName(entity, environment),
                         NamingHelperWCF.GetEntityServiceName(entity),
                         ServicesLayerConfig.Methods.GetProxyById(entity.Constraints.PrimaryId, environment).Signature);
            cw.BeginScope();
            cw.WriteLine("return {0}.{1}({2});",
                         NamingHelper.ToDTOTypeName(entity, environment),
                         ServicesLayerConfig.Methods.GetById(entity.Constraints.PrimaryId, environment).Name,
                         environment.ToArguments(entity.Constraints.PrimaryId.Attributes));
            cw.EndScope();
            cw.WriteLine();

            // Get by unique id
            foreach (IUniqueId uid in entity.Constraints.UniqueIds)
            {
                cw.WriteLine("{0} {1}.{2}",
                             NamingHelper.ToDTOTypeName(entity, environment),
                             NamingHelperWCF.GetEntityServiceName(entity),
                             ServicesLayerConfig.Methods.GetProxyByUniqueId(uid, environment).Signature);
                cw.BeginScope();
                cw.WriteLine("return {0}.{1}({2});",
                             NamingHelper.ToDTOTypeName(entity, environment),
                             ServicesLayerConfig.Methods.GetByUniqueId(uid, environment).Name,
                             environment.ToArguments(uid.Attributes));
                cw.EndScope();
            }

            cw.EndRegion();
            cw.WriteLine();
        }
        protected override void ProcessEntity(IEntity entity)
        {
            string supertypeName = ClassName_PersistentProxyAdapter;

            if (entity.HasSupertype)
            {
                supertypeName = environment.ToTypeName(entity.Supertype, true);
            }
            else if (!entity.Persistence.Persisted)
            {
                supertypeName = ClassName_ServiceProxyAdapter;
            }
            cw.BeginClass(AccessLevel.Public,
                          true,
                          entity.Name,
                          supertypeName);

            // Proxy accessor
            cw.BeginProperty(AccessLevel.Internal,
                             VirtualisationLevel.New,
                             NamingHelper.ToDTOTypeName(entity, servicesEnvironment),
                             PropertyName_DomainObjectProxy);
            cw.BeginPropertyGet();
            cw.WriteLine("return ({0})base.{1};",
                         NamingHelper.ToDTOTypeName(entity, servicesEnvironment),
                         PropertyName_DomainObjectProxy);
            cw.EndPropertyAccessor();
            cw.BeginPropertySet();
            cw.WriteLine("base.{0} = value;", PropertyName_DomainObjectProxy);
            cw.EndPropertyAccessor();
            cw.EndProperty();
            cw.WriteLine();

            // Constructors
            cw.BeginRegion("Constructors");
            cw.WriteLine("public {0}()", entity.Name);
            cw.BeginScope();
            cw.BeginUsing("{0} client = new {0}()", NamingHelperWCF.GetEntityServiceClient(entity));
            cw.WriteLine("{0} = client.{1};",
                         PropertyName_DomainObjectProxy,
                         NamingHelperWCF.MethodSignature_Create(entity));
            cw.WriteLine("client.Close();");
            cw.EndUsing();
            cw.EndScope();
            cw.WriteLine();

            cw.WriteLine("public {0}({1} source)",
                         entity.Name,
                         NamingHelper.ToDTOTypeName(entity, servicesEnvironment));
            cw.BeginScope();
            cw.WriteLine("if (source == null) throw new NullReferenceException(\"{0}\");",
                         "Source proxy object cannot be null");
            cw.WriteLine("this.{0} = source;", PropertyName_DomainObjectProxy);
            cw.EndScope();

            cw.EndRegion();
            cw.WriteLine();

            // Get by id
            cw.WriteLine("public static {0}{1} {2}",
                         entity.HasSupertype ? "new " : "",
                         entity.Name,
                         ServicesLayerConfig.Methods.GetById(entity.Constraints.PrimaryId, environment).Signature);
            cw.BeginScope();
            cw.BeginUsing("{0} client = new {0}()", NamingHelperWCF.GetEntityServiceClient(entity));
            cw.WriteLine("return new {0}(client.{1}({2}));",
                         entity.Name,
                         ServicesLayerConfig.Methods.GetProxyById(entity.Constraints.PrimaryId, environment).Name,
                         environment.ToArguments(entity.Constraints.PrimaryId.Attributes));
            cw.EndUsing();
            cw.EndScope();
            cw.WriteLine();

            // Get by unique id
            foreach (IUniqueId uid in entity.Constraints.UniqueIds)
            {
                cw.WriteLine("public static {0} {1}",
                             entity.Name,
                             ServicesLayerConfig.Methods.GetByUniqueId(uid, environment).Signature);
                cw.BeginScope();
                cw.BeginUsing("{0} client = new {0}()", NamingHelperWCF.GetEntityServiceClient(entity));
                cw.WriteLine("return new {0}(client.{1}({2}));",
                             entity.Name,
                             ServicesLayerConfig.Methods.GetProxyByUniqueId(uid, environment).Name,
                             environment.ToArguments(uid.Attributes));
                cw.EndUsing();
                cw.EndScope();
                cw.WriteLine();
            }

            ProcessAttributes(entity);

            cw.EndClass();
            cw.WriteLine();
        }