Commit db19ef3

mo khan <mo@mokhan.ca>
2010-07-22 00:47:23
imported some of the accounting domain i built in my spike project.
1 parent f5ed784
product/client/client.ui/bootstrappers/Bootstrapper.cs → product/client/client.ui/bootstrappers/ClientBootstrapper.cs
@@ -18,7 +18,7 @@ using Rhino.Queues;
 
 namespace presentation.windows.bootstrappers
 {
-    static public class Bootstrapper
+    static public class ClientBootstrapper
     {
         static public ShellWindow create_window()
         {
@@ -31,10 +31,7 @@ namespace presentation.windows.bootstrappers
             builder.Register(x => shell_window).SingletonScoped();
             builder.Register(x => shell_window).As<RegionManager>().SingletonScoped();
 
-            //needs startups
-            builder.Register<StartServiceBus>().As<NeedStartup>();
-            builder.Register<ComposeShell>().As<NeedStartup>();
-            builder.Register<ConfigureMappings>().As<NeedStartup>();
+            register_needs_startup(builder);
 
             // infrastructure
             builder.Register<Log4NetLogFactory>().As<LogFactory>().SingletonScoped();
@@ -46,15 +43,42 @@ namespace presentation.windows.bootstrappers
             builder.Register(x => new RhinoPublisher("server", 2200, manager)).As<ServiceBus>().SingletonScoped();
             builder.Register(x => new RhinoReceiver(manager.GetQueue("client"), x.Resolve<CommandProcessor>())).As<RhinoReceiver>().As<Receiver>().SingletonScoped();
 
-            // presentation infrastructure
+            register_presentation_infrastructure(builder);
+            register_presenters(builder);
+            register_for_message_to_listen_for(builder);
+
+            //shell_window.Closed += (o, e) => Resolve.the<ServiceBus>().publish<ApplicationShuttingDown>();
+            shell_window.Closed += (o, e) => Resolve.the<CommandProcessor>().stop();
+            shell_window.Closed += (o, e) => manager.Dispose();
+            shell_window.Closed += (o, e) => Resolve.the<IEnumerable<NeedsShutdown>>();
+
+            Resolve.the<IEnumerable<NeedStartup>>().each(x => x.run());
+            Resolve.the<CommandProcessor>().run();
+            return shell_window;
+        }
+
+        static void register_needs_startup(ContainerBuilder builder)
+        {
+            builder.Register<StartServiceBus>().As<NeedStartup>();
+            builder.Register<ComposeShell>().As<NeedStartup>();
+            builder.Register<ConfigureMappings>().As<NeedStartup>();
+        }
+
+        static void register_presentation_infrastructure(ContainerBuilder builder)
+        {
             SynchronizationContext.SetSynchronizationContext(new DispatcherSynchronizationContext());
             builder.Register<WpfApplicationController>().As<ApplicationController>().SingletonScoped();
             builder.Register<WpfPresenterFactory>().As<PresenterFactory>().SingletonScoped();
             builder.Register<SynchronizedEventAggregator>().As<EventAggregator>().SingletonScoped();
             //builder.Register(x => AsyncOperationManager.SynchronizationContext);
             builder.Register(x => SynchronizationContext.Current);
+            builder.Register<AsynchronousCommandProcessor>().As<CommandProcessor>().SingletonScoped();
+            //builder.Register<SynchronousCommandProcessor>().As<CommandProcessor>().SingletonScoped();
+            builder.Register<WPFCommandBuilder>().As<UICommandBuilder>();
+        }
 
-            // presenters
+        static void register_presenters(ContainerBuilder builder)
+        {
             builder.Register<StatusBarPresenter>().SingletonScoped();
             builder.Register<SelectedFamilyMemberPresenter>().SingletonScoped();
             builder.Register<AddFamilyMemberPresenter>();
@@ -64,22 +88,12 @@ namespace presentation.windows.bootstrappers
             builder.Register<CancelCommand>();
             builder.Register<AddNewDetailAccountPresenter>();
             builder.Register<AddNewDetailAccountPresenter.CreateNewAccount>();
+        }
 
-            // commanding
-            builder.Register<AsynchronousCommandProcessor>().As<CommandProcessor>().SingletonScoped();
-            //builder.Register<SynchronousCommandProcessor>().As<CommandProcessor>().SingletonScoped();
-            builder.Register<WPFCommandBuilder>().As<UICommandBuilder>();
-
-            // queries
+        static void register_for_message_to_listen_for(ContainerBuilder builder)
+        {
             builder.Register<PublishEventHandler<AddedNewFamilyMember>>().As<Handler>();
-
-            Resolve.the<IEnumerable<NeedStartup>>().each(x => x.run());
-            Resolve.the<CommandProcessor>().run();
-
-            shell_window.Closed += (o, e) => Resolve.the<ServiceBus>().publish<ApplicationShuttingDown>();
-            shell_window.Closed += (o, e) => Resolve.the<CommandProcessor>().stop();
-            shell_window.Closed += (o, e) => manager.Dispose();
-            return shell_window;
+            builder.Register<PublishEventHandler<NewAccountCreated>>().As<Handler>();
         }
     }
 }
\ No newline at end of file
product/client/client.ui/presenters/AddNewDetailAccountPresenter.cs
@@ -38,7 +38,7 @@ namespace presentation.windows.presenters
 
             protected override void run(AddNewDetailAccountPresenter presenter)
             {
-                bus.publish<common.messages.CreateNewDetailAccount>(x =>
+                bus.publish<common.messages.CreateNewDetailAccountCommand>(x =>
                 {
                     x.account_name = presenter.account_name;
                     x.currency = presenter.currency;
product/client/client.ui/presenters/PersonDetails.cs
@@ -13,7 +13,7 @@ namespace presentation.windows.presenters
 
         public override string ToString()
         {
-            return "{0} {1}".formatted_using(first_name, last_name);
+            return "{0} {1}".format(first_name, last_name);
         }
     }
 }
\ No newline at end of file
product/client/client.ui/views/ShellWIndow.xaml.cs
@@ -32,7 +32,7 @@ namespace presentation.windows.views
         void ensure_that_the_region_exists<Region>()
         {
             if (!regions.ContainsKey(typeof (Region)))
-                throw new Exception("Could not find region: {0}".formatted_using(typeof (Region)));
+                throw new Exception("Could not find region: {0}".format(typeof (Region)));
         }
     }
 }
\ No newline at end of file
product/client/client.ui/client.csproj
@@ -150,7 +150,7 @@
   </ItemGroup>
   <ItemGroup>
     <Compile Include="ApplicationController.cs" />
-    <Compile Include="bootstrappers\Bootstrapper.cs" />
+    <Compile Include="bootstrappers\ClientBootstrapper.cs" />
     <Compile Include="bootstrappers\ConfigureMappings.cs" />
     <Compile Include="bootstrappers\StartServiceBus.cs" />
     <Compile Include="events\SelectedFamilyMember.cs" />
product/client/client.ui/Program.cs
@@ -34,7 +34,7 @@ namespace presentation.windows
             new WPFApplication
             {
                 ShutdownMode = ShutdownMode.OnMainWindowClose,
-            }.Run(Bootstrapper.create_window());
+            }.Run(ClientBootstrapper.create_window());
         }
 
         static string get_service_startup_path(string[] args)
product/client/common/messages/CreateNewDetailAccount.cs → product/client/common/messages/CreateNewDetailAccountCommand.cs
@@ -5,7 +5,7 @@ namespace presentation.windows.common.messages
 {
     [Serializable]
     [ProtoContract]
-    public class CreateNewDetailAccount
+    public class CreateNewDetailAccountCommand
     {
         [ProtoMember(1)]
         public string account_name { get; set; }
product/client/common/messages/NewAccountCreated.cs
@@ -5,7 +5,7 @@ namespace presentation.windows.common.messages
 {
     [Serializable]
     [ProtoContract]
-    public class NewAccountCreated
+    public class NewAccountCreated : IEvent
     {
         [ProtoMember(1)]
         public string name { get; set; }
product/client/common/common.csproj
@@ -88,7 +88,7 @@
     <Compile Include="MessageHandler.cs" />
     <Compile Include="messages\AddedNewFamilyMember.cs" />
     <Compile Include="messages\ApplicationShuttingDown.cs" />
-    <Compile Include="messages\CreateNewDetailAccount.cs" />
+    <Compile Include="messages\CreateNewDetailAccountCommand.cs" />
     <Compile Include="messages\FamilyMemberToAdd.cs" />
     <Compile Include="messages\FindAllFamily.cs" />
     <Compile Include="messages\NewAccountCreated.cs" />
product/client/common/NeedStartup.cs
@@ -3,4 +3,6 @@ using gorilla.commons.utility;
 namespace presentation.windows.common
 {
     public interface NeedStartup : Command {}
+
+    public interface NeedsShutdown : Command {}
 }
\ No newline at end of file
product/client/common/RhinoPublisher.cs
@@ -30,7 +30,7 @@ namespace presentation.windows.common
         {
             using (var transaction = new TransactionScope(TransactionScopeOption.RequiresNew))
             {
-                var destination = "rhino.queues://localhost:{0}/{1}".formatted_using(port, destination_queue);
+                var destination = "rhino.queues://localhost:{0}/{1}".format(port, destination_queue);
                 this.log().debug("sending {0} to {1}", item, destination);
                 sender.Send(new Uri(destination), create_payload_from(item));
                 transaction.Complete();
product/client/server/domain/accounting/Account.cs
@@ -1,12 +1,11 @@
-using System;
+using Gorilla.Commons.Utility;
 
 namespace presentation.windows.server.domain.accounting
 {
-    public class Account
+    public interface Account
     {
-        static public Account New(string account_name, UnitOfMeasure units)
-        {
-            throw new NotImplementedException();
-        }
+        Quantity balance();
+        Quantity balance(Date date);
+        Quantity balance(Range<Date> period);
     }
 }
\ No newline at end of file
product/client/server/domain/accounting/AnonymousVisitor.cs
@@ -0,0 +1,20 @@
+using System;
+using gorilla.commons.utility;
+
+namespace presentation.windows.server.domain.accounting
+{
+    public class AnonymousVisitor<T> : Visitor<T>
+    {
+        readonly Action<T> action;
+
+        public AnonymousVisitor(Action<T> action)
+        {
+            this.action = action;
+        }
+
+        public void visit(T item_to_visit)
+        {
+            action(item_to_visit);
+        }
+    }
+}
\ No newline at end of file
product/client/server/domain/accounting/BOED.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace presentation.windows.server.domain.accounting
+{
+    public class BOED : SimpleUnitOfMeasure
+    {
+        public override string pretty_print(double amount)
+        {
+            throw new NotImplementedException();
+        }
+    }
+}
\ No newline at end of file
product/client/server/domain/accounting/Calendar.cs
@@ -0,0 +1,31 @@
+using System;
+using Gorilla.Commons.Utility;
+
+namespace presentation.windows.server.domain.accounting
+{
+    static public class Calendar
+    {
+        static Func<Date> date = () => DateTime.Now.Date;
+        static Func<Date> default_date = () => DateTime.Now.Date;
+
+        static public void stop(Func<Date> new_date)
+        {
+            date = new_date;
+        }
+
+        static public void start()
+        {
+            date = default_date;
+        }
+
+        static public Date now()
+        {
+            return date();
+        }
+
+        static public void reset()
+        {
+            date = default_date;
+        }
+    }
+}
\ No newline at end of file
product/client/server/domain/accounting/ConversionRatio.cs
@@ -0,0 +1,18 @@
+namespace presentation.windows.server.domain.accounting
+{
+    public class ConversionRatio
+    {
+        double rate;
+        static public readonly ConversionRatio Default = new ConversionRatio(1);
+
+        public ConversionRatio(double rate)
+        {
+            this.rate = rate;
+        }
+
+        public double applied_to(double amount)
+        {
+            return amount*rate;
+        }
+    }
+}
\ No newline at end of file
product/client/server/domain/accounting/Currency.cs
@@ -1,12 +1,66 @@
-using System;
+using System.Collections.Generic;
+using gorilla.commons.utility;
+using System.Linq;
 
 namespace presentation.windows.server.domain.accounting
 {
-    public class Currency : UnitOfMeasure
+    public class Currency : SimpleUnitOfMeasure
     {
-        static public Currency named(string currency)
+        static public readonly List<Currency> all = new List<Currency>();
+        static public readonly Currency USD = new Currency("USD");
+        static public readonly Currency CAD = new Currency("CAD");
+
+        Currency(string pneumonic)
+        {
+            this.pneumonic = pneumonic;
+            all.add(this);
+        }
+
+        public override string pretty_print(double amount)
+        {
+            return "{0:C} {1}".format(amount, this);
+        }
+
+        public bool Equals(Currency other)
+        {
+            if (ReferenceEquals(null, other)) return false;
+            if (ReferenceEquals(this, other)) return true;
+            return Equals(other.pneumonic, pneumonic);
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != typeof (Currency)) return false;
+            return Equals((Currency) obj);
+        }
+
+        public override int GetHashCode()
+        {
+            return (pneumonic != null ? pneumonic.GetHashCode() : 0);
+        }
+
+        static public bool operator ==(Currency left, Currency right)
+        {
+            return Equals(left, right);
+        }
+
+        static public bool operator !=(Currency left, Currency right)
+        {
+            return !Equals(left, right);
+        }
+
+        public override string ToString()
+        {
+            return pneumonic;
+        }
+
+        string pneumonic;
+
+        static public UnitOfMeasure named(string currency)
         {
-            throw new NotImplementedException();
+            return all.Single(x => x.pneumonic.Equals(currency));
         }
     }
 }
\ No newline at end of file
product/client/server/domain/accounting/DateRange.cs
@@ -0,0 +1,17 @@
+using Gorilla.Commons.Utility;
+
+namespace presentation.windows.server.domain.accounting
+{
+    static public class DateRange
+    {
+        static public Range<Date> up_to(Date date)
+        {
+            return Date.First.to(date);
+        }
+
+        static public Range<Date> to(this Date start, Date end)
+        {
+            return new SequentialRange<Date>(start, end);
+        }
+    }
+}
\ No newline at end of file
product/client/server/domain/accounting/Deposit.cs
@@ -0,0 +1,10 @@
+namespace presentation.windows.server.domain.accounting
+{
+    public class Deposit : TransactionType
+    {
+        public Quantity adjust(Quantity balance, Quantity adjustment)
+        {
+            return balance.plus(adjustment);
+        }
+    }
+}
\ No newline at end of file
product/client/server/domain/accounting/DetailAccount.cs
@@ -0,0 +1,69 @@
+using System.Collections.Generic;
+using gorilla.commons.utility;
+using Gorilla.Commons.Utility;
+
+namespace presentation.windows.server.domain.accounting
+{
+    public class DetailAccount : Entity, Account, Visitable<Entry>
+    {
+        protected DetailAccount() {}
+
+        DetailAccount(UnitOfMeasure unit_of_measure)
+        {
+            this.unit_of_measure = unit_of_measure;
+        }
+
+        static public DetailAccount New(UnitOfMeasure unit_of_measure)
+        {
+            return new DetailAccount(unit_of_measure);
+        }
+
+        public virtual void deposit(double amount)
+        {
+            deposit(amount, unit_of_measure);
+        }
+
+        public virtual void deposit(double amount, UnitOfMeasure units)
+        {
+            add(Entry.New<Deposit>(amount, units));
+        }
+
+        public virtual void withdraw(double amount, UnitOfMeasure units)
+        {
+            add(Entry.New<Withdrawal>(amount, units));
+        }
+
+        public virtual void add(Entry new_entry)
+        {
+            entries.Add(new_entry);
+        }
+
+        public virtual Quantity balance()
+        {
+            return balance(Calendar.now());
+        }
+
+        public virtual Quantity balance(Date date)
+        {
+            return balance(DateRange.up_to(date));
+        }
+
+        public virtual Quantity balance(Range<Date> period)
+        {
+            var result = new Quantity(0, unit_of_measure);
+            accept(new AnonymousVisitor<Entry>(x =>
+            {
+                if (x.booked_in(period)) result = x.adjust(result);
+            }));
+            return result;
+        }
+
+        public virtual void accept(Visitor<Entry> visitor)
+        {
+            foreach (var entry in entries) visitor.visit(entry);
+        }
+
+        IList<Entry> entries = new List<Entry>();
+        UnitOfMeasure unit_of_measure;
+    }
+}
\ No newline at end of file
product/client/server/domain/accounting/Entry.cs
@@ -0,0 +1,36 @@
+using Gorilla.Commons.Utility;
+
+namespace presentation.windows.server.domain.accounting
+{
+    public class Entry
+    {
+        static public Entry New<Transaction>(double amount, UnitOfMeasure units) where Transaction : TransactionType, new()
+        {
+            return New<Transaction>(new Quantity(amount, units));
+        }
+
+        static public Entry New<Transaction>(Quantity amount) where Transaction : TransactionType, new()
+        {
+            return new Entry
+                   {
+                       when_booked = Calendar.now(),
+                       transaction_type = new Transaction(),
+                       amount = amount,
+                   };
+        }
+
+        public virtual Quantity adjust(Quantity balance)
+        {
+            return transaction_type.adjust(balance, amount);
+        }
+
+        public virtual bool booked_in(Range<Date> period)
+        {
+            return period.includes(when_booked);
+        }
+
+        Date when_booked;
+        TransactionType transaction_type;
+        Quantity amount;
+    }
+}
\ No newline at end of file
product/client/server/domain/accounting/MCF.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace presentation.windows.server.domain.accounting
+{
+    public class MCF : SimpleUnitOfMeasure
+    {
+        public override string pretty_print(double amount)
+        {
+            throw new NotImplementedException();
+        }
+    }
+}
\ No newline at end of file
product/client/server/domain/accounting/Potential.cs
@@ -0,0 +1,27 @@
+namespace presentation.windows.server.domain.accounting
+{
+    public class Potential<Transaction> : PotentialEntry where Transaction : TransactionType, new()
+    {
+        static public Potential<Transaction> New(DetailAccount destination, Quantity amount)
+        {
+            return new Potential<Transaction>
+                   {
+                       account = destination,
+                       amount = amount,
+                   };
+        }
+
+        public Quantity combined_with(Quantity other)
+        {
+            return new Transaction().adjust(other, amount);
+        }
+
+        public void commit()
+        {
+            account.add(Entry.New<Transaction>(amount));
+        }
+
+        DetailAccount account;
+        Quantity amount;
+    }
+}
\ No newline at end of file
product/client/server/domain/accounting/PotentialEntry.cs
@@ -0,0 +1,8 @@
+namespace presentation.windows.server.domain.accounting
+{
+    public interface PotentialEntry
+    {
+        Quantity combined_with(Quantity other);
+        void commit();
+    }
+}
\ No newline at end of file
product/client/server/domain/accounting/Quantity.cs
@@ -0,0 +1,64 @@
+using System;
+
+namespace presentation.windows.server.domain.accounting
+{
+    public class Quantity : IEquatable<Quantity>
+    {
+        double amount;
+        UnitOfMeasure units;
+
+        public Quantity(double amount, UnitOfMeasure units)
+        {
+            this.units = units;
+            this.amount = amount;
+        }
+
+        public Quantity plus(Quantity other)
+        {
+            return new Quantity(amount + other.convert_to(units).amount, units);
+        }
+
+        public Quantity subtract(Quantity other)
+        {
+            return new Quantity(amount - other.convert_to(units).amount, units);
+        }
+
+        public Quantity convert_to(UnitOfMeasure unit_of_measure)
+        {
+            return new Quantity(unit_of_measure.convert(amount, units), unit_of_measure);
+        }
+
+        static public implicit operator double(Quantity quanity)
+        {
+            return quanity.amount;
+        }
+
+        public bool Equals(Quantity other)
+        {
+            if (ReferenceEquals(null, other)) return false;
+            if (ReferenceEquals(this, other)) return true;
+            return other.amount.Equals(amount) && Equals(other.units, units);
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != typeof (Quantity)) return false;
+            return Equals((Quantity) obj);
+        }
+
+        public override int GetHashCode()
+        {
+            unchecked
+            {
+                return (amount.GetHashCode()*397) ^ (units != null ? units.GetHashCode() : 0);
+            }
+        }
+
+        public override string ToString()
+        {
+            return units.pretty_print(amount);
+        }
+    }
+}
\ No newline at end of file
product/client/server/domain/accounting/Range.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace presentation.windows.server.domain.accounting
+{
+    public interface Range<T> where T : IComparable<T>
+    {
+        bool includes(T item);
+    }
+}
\ No newline at end of file
product/client/server/domain/accounting/SequentialRange.cs
@@ -0,0 +1,27 @@
+using System;
+using gorilla.commons.utility;
+
+namespace presentation.windows.server.domain.accounting
+{
+    public class SequentialRange<T> : Range<T> where T : IComparable<T>
+    {
+        readonly T start;
+        readonly T end;
+
+        public SequentialRange(T start, T end)
+        {
+            this.start = start;
+            this.end = end;
+        }
+
+        public bool includes(T item)
+        {
+            return item.CompareTo(start) >= 0 && item.CompareTo(end) <= 0;
+        }
+
+        public override string ToString()
+        {
+            return "{0} to {1}".format(start, end);
+        }
+    }
+}
\ No newline at end of file
product/client/server/domain/accounting/SimpleUnitOfMeasure.cs
@@ -0,0 +1,21 @@
+namespace presentation.windows.server.domain.accounting
+{
+    public delegate ConversionRatio RateTable(UnitOfMeasure unitCurrency, UnitOfMeasure referenceCurrency);
+
+    public abstract class SimpleUnitOfMeasure : UnitOfMeasure
+    {
+        public double convert(double amount, UnitOfMeasure other)
+        {
+            return rate_table(this, other).applied_to(amount);
+        }
+
+        public abstract string pretty_print(double amount);
+
+        static RateTable rate_table = (x, y) => ConversionRatio.Default;
+
+        static public void provide_rate(RateTable current_rates)
+        {
+            rate_table = current_rates;
+        }
+    }
+}
\ No newline at end of file
product/client/server/domain/accounting/SummaryAccount.cs
@@ -0,0 +1,42 @@
+using System.Collections.Generic;
+using gorilla.commons.utility;
+using Gorilla.Commons.Utility;
+
+namespace presentation.windows.server.domain.accounting
+{
+    public class SummaryAccount : Account
+    {
+        static public SummaryAccount New(UnitOfMeasure unit_of_measure)
+        {
+            return new SummaryAccount
+                   {
+                       unit_of_measure = unit_of_measure
+                   };
+        }
+
+        public void add(Account account)
+        {
+            accounts.Add(account);
+        }
+
+        public Quantity balance()
+        {
+            return balance(Calendar.now());
+        }
+
+        public Quantity balance(Date date)
+        {
+            return balance(DateRange.up_to(date));
+        }
+
+        public Quantity balance(Range<Date> period)
+        {
+            var result = new Quantity(0, unit_of_measure);
+            accounts.each(x => result = result.plus(x.balance(period)));
+            return result;
+        }
+
+        ICollection<Account> accounts = new HashSet<Account>();
+        UnitOfMeasure unit_of_measure;
+    }
+}
\ No newline at end of file
product/client/server/domain/accounting/Transaction.cs
@@ -0,0 +1,54 @@
+using System.Collections.Generic;
+using System.Linq;
+using gorilla.commons.utility;
+
+namespace presentation.windows.server.domain.accounting
+{
+    public class Transaction
+    {
+        static public Transaction New(UnitOfMeasure reference_units)
+        {
+            return new Transaction(reference_units);
+        }
+
+        Transaction(UnitOfMeasure reference)
+        {
+            reference_units = reference;
+        }
+
+        public void deposit(DetailAccount destination, Quantity amount)
+        {
+            deposits.Add(Potential<Deposit>.New(destination, amount));
+        }
+
+        public void withdraw(DetailAccount source, Quantity amount)
+        {
+            withdrawals.Add(Potential<Withdrawal>.New(source, amount));
+        }
+
+        public void post()
+        {
+            ensure_zero_balance();
+            deposits.Union(withdrawals).each(x => x.commit());
+        }
+
+        void ensure_zero_balance()
+        {
+            var balance = calculate_total(deposits.Union(withdrawals));
+            if (balance == 0) return;
+
+            throw new TransactionDoesNotBalance();
+        }
+
+        Quantity calculate_total(IEnumerable<PotentialEntry> potential_transactions)
+        {
+            var result = new Quantity(0, reference_units);
+            potential_transactions.each(x => result = x.combined_with(result));
+            return result;
+        }
+
+        List<PotentialEntry> deposits = new List<PotentialEntry>();
+        List<PotentialEntry> withdrawals = new List<PotentialEntry>();
+        UnitOfMeasure reference_units;
+    }
+}
\ No newline at end of file
product/client/server/domain/accounting/TransactionDoesNotBalance.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace presentation.windows.server.domain.accounting
+{
+    public class TransactionDoesNotBalance : Exception
+    {
+        
+    }
+}
\ No newline at end of file
product/client/server/domain/accounting/TransactionType.cs
@@ -0,0 +1,7 @@
+namespace presentation.windows.server.domain.accounting
+{
+    public interface TransactionType
+    {
+        Quantity adjust(Quantity balance, Quantity adjustment);
+    }
+}
\ No newline at end of file
product/client/server/domain/accounting/UnitOfMeasure.cs
@@ -1,4 +1,9 @@
 namespace presentation.windows.server.domain.accounting
 {
-    public interface UnitOfMeasure {}
+    public interface UnitOfMeasure
+    {
+        double convert(double amount, UnitOfMeasure other);
+        string pretty_print(double amount);
+    }
+
 }
\ No newline at end of file
product/client/server/domain/accounting/Withdrawal.cs
@@ -0,0 +1,10 @@
+namespace presentation.windows.server.domain.accounting
+{
+    public class Withdrawal : TransactionType
+    {
+        public Quantity adjust(Quantity balance, Quantity adjustment)
+        {
+            return balance.subtract(adjustment);
+        }
+    }
+}
\ No newline at end of file
product/client/server/domain/Entity.cs
@@ -10,7 +10,7 @@ namespace presentation.windows.server.domain
             id = Id<Guid>.Default;
         }
 
-        public virtual Guid id { get; private set; }
+        public virtual Guid id { get;  set; }
 
         public virtual bool Equals(Entity other)
         {
product/client/server/handlers/SaveNewAccountCommand.cs → product/client/server/handlers/CreateNewDetailAccountHandler.cs
@@ -5,20 +5,20 @@ using presentation.windows.server.orm;
 
 namespace presentation.windows.server.handlers
 {
-    public class SaveNewAccountCommand : AbstractHandler<CreateNewDetailAccount>
+    public class CreateNewDetailAccountHandler : AbstractHandler<CreateNewDetailAccountCommand>
     {
         AccountRepository accounts;
         ServiceBus bus;
 
-        public SaveNewAccountCommand(AccountRepository accounts, ServiceBus bus)
+        public CreateNewDetailAccountHandler(AccountRepository accounts, ServiceBus bus)
         {
             this.accounts = accounts;
             this.bus = bus;
         }
 
-        public override void handle(CreateNewDetailAccount item)
+        public override void handle(CreateNewDetailAccountCommand item)
         {
-            accounts.save(Account.New(item.account_name, Currency.named(item.currency)));
+            accounts.save(DetailAccount.New(Currency.named(item.currency)));
             bus.publish<NewAccountCreated>(x => x.name = item.account_name);
         }
     }
product/client/server/orm/mappings/DetailAccountMapping.cs
@@ -0,0 +1,13 @@
+using FluentNHibernate.Mapping;
+using presentation.windows.server.domain.accounting;
+
+namespace presentation.windows.server.orm.mappings
+{
+    public class DetailAccountMapping : ClassMap<DetailAccount>
+    {
+        public DetailAccountMapping()
+        {
+            Id(x => x.id).GeneratedBy.GuidComb();
+        }
+    }
+}
\ No newline at end of file
product/client/server/NHibernateBootstrapper.cs
@@ -14,8 +14,8 @@ namespace presentation.windows.server
 {
     public class NHibernateBootstrapper : Query<ISessionFactory>
     {
-        private string database_path;
-        private string connection_string;
+        string database_path;
+        string connection_string;
 
         public NHibernateBootstrapper()
         {
@@ -34,15 +34,18 @@ namespace presentation.windows.server
                               //.ShowSql()
                               .ProxyFactoryFactory<ProxyFactoryFactory>()
                 )
-                .Mappings(x => { x.FluentMappings.AddFromAssemblyOf<MappingAssembly>(); })
+                .Mappings(x =>
+                {
+                    x.FluentMappings.AddFromAssemblyOf<MappingAssembly>();
+                })
                 .ExposeConfiguration(x => export(x)).BuildSessionFactory();
         }
 
-        private void export(Configuration configuration)
+        void export(Configuration configuration)
         {
+            if (File.Exists(database_path)) File.Delete(database_path);
             using (var engine = new SqlCeEngine(connection_string))
             {
-                if (File.Exists(database_path)) File.Delete(database_path);
                 engine.CreateDatabase();
             }
             new SchemaExport(configuration).Execute(true, true, false);
product/client/server/Program.cs
@@ -27,7 +27,7 @@ namespace presentation.windows.server
                     catch { }
                     Environment.Exit(Environment.ExitCode);
                 };
-                Bootstrapper.run();
+                ServerBootstrapper.run();
                 Console.ReadLine();
             }
             catch (Exception e)
product/client/server/server.csproj
@@ -41,7 +41,7 @@
     <DefineConstants>DEBUG;TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
-    <PlatformTarget>x86</PlatformTarget>
+    <PlatformTarget>AnyCPU</PlatformTarget>
     <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
@@ -111,8 +111,29 @@
   </ItemGroup>
   <ItemGroup>
     <Compile Include="ConfigureApplicationDirectory.cs" />
+    <Compile Include="domain\accounting\AnonymousVisitor.cs" />
+    <Compile Include="domain\accounting\BOED.cs" />
+    <Compile Include="domain\accounting\Calendar.cs" />
+    <Compile Include="domain\accounting\ConversionRatio.cs" />
+    <Compile Include="domain\accounting\DateRange.cs" />
+    <Compile Include="domain\accounting\Deposit.cs" />
+    <Compile Include="domain\accounting\DetailAccount.cs" />
+    <Compile Include="domain\accounting\Entry.cs" />
+    <Compile Include="domain\accounting\MCF.cs" />
+    <Compile Include="domain\accounting\Potential.cs" />
+    <Compile Include="domain\accounting\PotentialEntry.cs" />
+    <Compile Include="domain\accounting\Quantity.cs" />
+    <Compile Include="domain\accounting\Range.cs" />
+    <Compile Include="domain\accounting\SequentialRange.cs" />
+    <Compile Include="domain\accounting\SimpleUnitOfMeasure.cs" />
+    <Compile Include="domain\accounting\SummaryAccount.cs" />
+    <Compile Include="domain\accounting\Transaction.cs" />
+    <Compile Include="domain\accounting\TransactionDoesNotBalance.cs" />
+    <Compile Include="domain\accounting\TransactionType.cs" />
+    <Compile Include="domain\accounting\Withdrawal.cs" />
     <Compile Include="handlers\AddNewFamilyMemberHandler.cs" />
-    <Compile Include="Bootstrapper.cs" />
+    <Compile Include="orm\mappings\DetailAccountMapping.cs" />
+    <Compile Include="ServerBootstrapper.cs" />
     <Compile Include="ConfigureMappings.cs" />
     <Compile Include="domain\accounting\Account.cs" />
     <Compile Include="domain\accounting\Currency.cs" />
@@ -127,7 +148,7 @@
     <Compile Include="domain\payroll\UnitPrice.cs" />
     <Compile Include="domain\Person.cs" />
     <Compile Include="handlers\FindAllFamilyHandler.cs" />
-    <Compile Include="handlers\SaveNewAccountCommand.cs" />
+    <Compile Include="handlers\CreateNewDetailAccountHandler.cs" />
     <Compile Include="handlers\ShutdownApplicationCommand.cs" />
     <Compile Include="NHibernateBootstrapper.cs" />
     <Compile Include="orm\AccountRepository.cs" />
product/client/server/Bootstrapper.cs → product/client/server/ServerBootstrapper.cs
@@ -18,7 +18,7 @@ using ISessionFactory = NHibernate.ISessionFactory;
 
 namespace presentation.windows.server
 {
-    public class Bootstrapper
+    public class ServerBootstrapper
     {
         static public void run()
         {
@@ -48,23 +48,27 @@ namespace presentation.windows.server
             builder.Register<NHibernateUnitOfWorkFactory>().As<IUnitOfWorkFactory>();
             builder.Register<IContext>(x => create_application_context()).SingletonScoped();
 
-            // commanding
-            //builder.Register<ContainerCommandBuilder>().As<CommandBuilder>().SingletonScoped();
-            //builder.Register<AsynchronousCommandProcessor>().As<CommandProcessor>().SingletonScoped();
+            register_handlers(builder);
+            register_repositories(builder);
+
+            Resolve.the<IEnumerable<NeedStartup>>().each(x => x.run());
+            Resolve.the<CommandProcessor>().run();
+        }
+
+        static void register_handlers(ContainerBuilder builder)
+        {
             builder.Register<SynchronousCommandProcessor>().As<CommandProcessor>().SingletonScoped();
             builder.Register<AddNewFamilyMemberHandler>().As<Handler>();
             builder.Register<FindAllFamilyHandler>().As<Handler>();
-            builder.Register<SaveNewAccountCommand>().As<Handler>();
+            builder.Register<CreateNewDetailAccountHandler>().As<Handler>();
             builder.Register<ShutdownApplicationCommand>().As<Handler>();
 
-            // queries
+        }
 
-            // repositories
+        static void register_repositories(ContainerBuilder builder)
+        {
             builder.Register<NHibernatePersonRepository>().As<PersonRepository>().FactoryScoped();
             builder.Register<NHibernateAccountRepository>().As<AccountRepository>().FactoryScoped();
-
-            Resolve.the<IEnumerable<NeedStartup>>().each(x => x.run());
-            Resolve.the<CommandProcessor>().run();
         }
 
         static IContext create_application_context()
product/commons/infrastructure/container/DependencyResolutionException.cs
@@ -6,7 +6,7 @@ namespace Gorilla.Commons.Infrastructure.Container
     public class DependencyResolutionException<T> : Exception
     {
         public DependencyResolutionException(Exception inner_exception)
-            : base("Could not resolve {0}".formatted_using(typeof (T).FullName), inner_exception)
+            : base("Could not resolve {0}".format(typeof (T).FullName), inner_exception)
         {
         }
     }
product/commons/infrastructure/logging/TextLogger.cs
@@ -22,7 +22,7 @@ namespace Gorilla.Commons.Infrastructure.Logging
         public void debug(string formatted_string, params object[] arguments)
         {
             writer.WriteLine("[{0}] - {1}", Thread.CurrentThread.ManagedThreadId,
-                             formatted_string.formatted_using(arguments));
+                             formatted_string.format(arguments));
         }
 
         public void error(Exception e)
product/commons/utility/Date.cs
@@ -8,6 +8,8 @@ namespace Gorilla.Commons.Utility
     public class Date :  IComparable<Date>, IComparable, IEquatable<Date>
     {
         readonly long ticks;
+        static public readonly Date First = new Date(DateTime.MinValue);
+        static public readonly Date Last = new Date(DateTime.MaxValue);
 
         public Date( DateTime date)
         {
product/commons/utility/RegistryExtensions.cs
@@ -17,7 +17,7 @@ namespace gorilla.commons.utility
             }
             catch (Exception exception)
             {
-                throw new Exception("Could Not Find an implementation of".formatted_using(typeof (K)), exception);
+                throw new Exception("Could Not Find an implementation of".format(typeof (K)), exception);
             }
         }
 
product/commons/utility/StringExtensions.cs
@@ -2,7 +2,7 @@ namespace gorilla.commons.utility
 {
     static public class StringExtensions
     {
-        static public string formatted_using(this string formatted_string, params object[] arguments)
+        static public string format(this string formatted_string, params object[] arguments)
         {
             return string.Format(formatted_string, arguments);
         }
@@ -19,7 +19,7 @@ namespace gorilla.commons.utility
 
         static public string to_string<T>(this T item)
         {
-            return "{0}".formatted_using(item);
+            return "{0}".format(item);
         }
     }
 }
\ No newline at end of file
product/support/unit/server/domain/accounting/BOEDSpecs.cs
@@ -0,0 +1,47 @@
+using Machine.Specifications;
+using presentation.windows.server.domain.accounting;
+
+namespace unit.server.domain.accounting
+{
+    public class BOEDSpecs
+    {
+        public abstract class concern
+        {
+            Establish context = () =>
+            {
+                sut = new BOED();
+            };
+
+            Cleanup c = () =>
+            {
+                SimpleUnitOfMeasure.provide_rate((x, y) => ConversionRatio.Default);
+            };
+
+            static protected BOED sut;
+        }
+
+        [Subject(typeof (BOED))]
+        public class when_converting_one_barrel_of_oil_equivalent_to_one_mcf : concern
+        {
+            Establish c = () =>
+            {
+                SimpleUnitOfMeasure.provide_rate((x, y) =>
+                {
+                    return new ConversionRatio(6);
+                });
+            };
+
+            Because b = () =>
+            {
+                result = sut.convert(1, new MCF());
+            };
+
+            It should_return_the_corrent_value = () =>
+            {
+                result.should_be_equal_to(6);
+            };
+
+            static double result;
+        }
+    }
+}
\ No newline at end of file
product/support/unit/server/domain/accounting/CurrencySpecs.cs
@@ -0,0 +1,44 @@
+using Machine.Specifications;
+using presentation.windows.server.domain.accounting;
+
+namespace unit.server.domain.accounting
+{
+    public class CurrencySpecs
+    {
+        public abstract class concern 
+        {
+            Cleanup cleanup = () =>
+            {
+                SimpleUnitOfMeasure.provide_rate((x, y) => ConversionRatio.Default);
+            };
+        }
+
+        [Subject(typeof (Currency))]
+        public class when_converting_one_USD_dollar_to_CAD : concern
+        {
+            Establish c = () =>
+            {
+                SimpleUnitOfMeasure.provide_rate((x, y) => new ConversionRatio(1.05690034));
+            };
+
+            It should_return_the_correct_amount = () =>
+            {
+                Currency.USD.convert(1, Currency.CAD).should_be_equal_to(1.05690034);
+            };
+        }
+
+        [Subject(typeof (Currency))]
+        public class when_converting_one_CAD_dollar_to_USD : concern
+        {
+            Establish c = () =>
+            {
+                SimpleUnitOfMeasure.provide_rate((x, y) => new ConversionRatio(0.95057));
+            };
+
+            It should_return_the_correct_amount = () =>
+            {
+                Currency.CAD.convert(1.05690034d, Currency.USD).should_be_equal_to(1.0046577561938002d);
+            };
+        }
+    }
+}
\ No newline at end of file
product/support/unit/server/domain/accounting/DetailAccountSpecs.cs
@@ -0,0 +1,47 @@
+using Machine.Specifications;
+using presentation.windows.server.domain.accounting;
+
+namespace unit.server.domain.accounting
+{
+    public class DetailAccountSpecs
+    {
+        public abstract class concern
+        {
+            Establish c = () =>
+            {
+                sut = DetailAccount.New(Currency.CAD);
+            };
+
+            static protected DetailAccount sut;
+        }
+
+        [Subject(typeof (DetailAccount))]
+        public class when_depositing_money_in_to_an_account : concern
+        {
+            Because b = () =>
+            {
+                sut.deposit(100.01, Currency.CAD);
+            };
+
+            It should_adjust_the_balance = () =>
+            {
+                sut.balance().should_be_equal_to(new Quantity(100.01, Currency.CAD));
+            };
+        }
+
+        [Subject(typeof (DetailAccount))]
+        public class when_withdrawing_money_from_an_account : concern
+        {
+            Because b = () =>
+            {
+                sut.deposit(100.01);
+                sut.withdraw(10.00, Currency.CAD);
+            };
+
+            It should_adjust_the_balance = () =>
+            {
+                sut.balance().should_be_equal_to(new Quantity(90.01, Currency.CAD));
+            };
+        }
+    }
+}
\ No newline at end of file
product/support/unit/server/domain/accounting/QuantitySpecs.cs
@@ -0,0 +1,37 @@
+using Machine.Specifications;
+using presentation.windows.server.domain.accounting;
+
+namespace unit.server.domain.accounting
+{
+    public class QuantitySpecs
+    {
+        public abstract class concern 
+        {
+            Establish c = () =>
+            {
+                sut = new Quantity(100, Currency.CAD);
+            };
+
+            static protected Quantity sut;
+        }
+
+        [Subject(typeof (Quantity))]
+        public class when_checking_if_two_quantities_are_equal : concern
+        {
+            It should_return_true_when_they_represent_the_same_amount_and_units = () =>
+            {
+                sut.should_be_equal_to(new Quantity(100, Currency.CAD));
+            };
+
+            It should_return_false_when_they_are_not_the_same_amount = () =>
+            {
+                sut.should_not_be_equal_to(new Quantity(1, Currency.CAD));
+            };
+
+            It should_return_false_when_they_represent_different_currencies = () =>
+            {
+                sut.should_not_be_equal_to(new Quantity(100, Currency.USD));
+            };
+        }
+    }
+}
\ No newline at end of file
product/support/unit/server/domain/accounting/SummaryAccountSpecs.cs
@@ -0,0 +1,42 @@
+using System;
+using Machine.Specifications;
+using presentation.windows.server.domain.accounting;
+
+namespace unit.server.domain.accounting
+{
+    public class SummaryAccountSpecs
+    {
+        [Subject(typeof (SummaryAccount))]
+        public class when_retrieving_the_balance_from_a_summary_account
+        {
+            Establish c = () =>
+            {
+                cash = DetailAccount.New(Currency.CAD);
+                cash.id = Guid.NewGuid();
+                credit = DetailAccount.New(Currency.CAD);
+                credit.id = Guid.NewGuid();
+
+                cash.deposit(50, Currency.CAD);
+                credit.deposit(50, Currency.CAD);
+                sut = SummaryAccount.New(Currency.CAD);
+            };
+
+            Because b = () =>
+            {
+                sut.add(cash);
+                sut.add(credit);
+                result = sut.balance();
+            };
+
+            It should_sum_the_balance_for_each_detail_account = () =>
+            {
+                result.should_be_equal_to(new Quantity(100.00, Currency.CAD));
+            };
+
+            static Quantity result;
+            static DetailAccount cash;
+            static DetailAccount credit;
+            static protected SummaryAccount sut;
+        }
+    }
+}
\ No newline at end of file
product/support/unit/server/domain/accounting/TransactionSpecs.cs
@@ -0,0 +1,115 @@
+using System;
+using Machine.Specifications;
+using presentation.windows.server.domain.accounting;
+
+namespace unit.server.domain.accounting
+{
+    public class TransactionSpecs
+    {
+        public abstract class concern 
+        {
+            Establish c = () =>
+            {
+                sut = Transaction.New(Currency.CAD);
+            };
+
+            static protected Transaction sut;
+        }
+
+        [Subject(typeof (Transaction))]
+        public class when_transferring_funds_from_one_account_to_another : concern
+        {
+            Establish c = () =>
+            {
+                source_account = DetailAccount.New(Currency.CAD);
+                destination_account = DetailAccount.New(Currency.CAD);
+                source_account.add(Entry.New<Deposit>(100, Currency.CAD));
+            };
+
+            Because b = () =>
+            {
+                sut.deposit(destination_account, new Quantity(100, Currency.CAD));
+                sut.withdraw(source_account, new Quantity(100, Currency.CAD));
+                sut.post();
+            };
+
+            It should_increase_the_balance_of_the_destination_account = () =>
+            {
+                destination_account.balance().should_be_equal_to(new Quantity(100, Currency.CAD));
+            };
+
+            It should_decrease_the_balance_of_the_source_account = () =>
+            {
+                source_account.balance().should_be_equal_to(new Quantity(0, Currency.CAD));
+            };
+
+            static DetailAccount source_account;
+            static DetailAccount destination_account;
+        }
+
+        [Subject(typeof (Transaction))]
+        public class when_transferring_funds_from_one_account_to_multiple_accounts : concern
+        {
+            Establish c = () =>
+            {
+                chequing = DetailAccount.New(Currency.CAD);
+                savings = DetailAccount.New(Currency.CAD);
+                rrsp = DetailAccount.New(Currency.CAD);
+                chequing.add(Entry.New<Deposit>(100, Currency.CAD));
+            };
+
+            Because b = () =>
+            {
+                sut.withdraw(chequing, new Quantity(100, Currency.CAD));
+                sut.deposit(savings, new Quantity(75, Currency.CAD));
+                sut.deposit(rrsp, new Quantity(25, Currency.CAD));
+                sut.post();
+            };
+
+            It should_increase_the_balance_of_each_destination_account = () =>
+            {
+                savings.balance().should_be_equal_to(new Quantity(75, Currency.CAD));
+                rrsp.balance().should_be_equal_to(new Quantity(25, Currency.CAD));
+            };
+
+            It should_decrease_the_balance_of_the_source_account = () =>
+            {
+                chequing.balance().should_be_equal_to(new Quantity(0, Currency.CAD));
+            };
+
+            static DetailAccount chequing;
+            static DetailAccount savings;
+            static DetailAccount rrsp;
+        }
+
+        [Subject(typeof (Transaction))]
+        public class when_a_transaction_does_not_reconcile_to_a_zero_balance : concern
+        {
+            Establish c = () =>
+            {
+                chequing = DetailAccount.New(Currency.CAD);
+                savings = DetailAccount.New(Currency.CAD);
+                chequing.add(Entry.New<Deposit>(100, Currency.CAD));
+            };
+
+            Because b = () =>
+            {
+                sut.withdraw(chequing, new Quantity(1, Currency.CAD));
+                sut.deposit(savings, new Quantity(100, Currency.CAD));
+                call = () =>
+                {
+                    sut.post();
+                };
+            };
+
+            It should_not_transfer_any_money = () =>
+            {
+                call.should_have_thrown<TransactionDoesNotBalance>();
+            };
+
+            static DetailAccount chequing;
+            static DetailAccount savings;
+            static Action call;
+        }
+    }
+}
\ No newline at end of file
product/support/unit/AssertionExtensions.cs
@@ -0,0 +1,54 @@
+using System;
+using Machine.Specifications;
+
+namespace unit
+{
+    static public class AssertionExtensions
+    {
+        static public void should_not_be_null<T>(this T item)
+        {
+            item.ShouldNotBeNull();
+        }
+
+        static public void should_be_an_instance_of<T>(this object actual)
+        {
+            actual.ShouldBeOfType(typeof (T));
+        }
+
+        static public void should_be_equal_to<T>(this T actual, T expected)
+        {
+            actual.ShouldEqual(expected);
+        }
+
+        static public void should_not_be_equal_to<T>(this T actual, T expected)
+        {
+            actual.ShouldNotEqual(expected);
+        }
+
+        static public void should_be_true(this bool actual)
+        {
+            actual.ShouldBeTrue();
+        }
+
+        static public void should_be_false(this bool actual)
+        {
+            actual.ShouldBeFalse();
+        }
+
+        static public void should_have_thrown<Exception>(this Action action) where Exception : System.Exception
+        {
+            try
+            {
+                action();
+                throw new System.Exception("Did not throw.");
+            }
+            catch (Exception e)
+            {
+                if (!e.GetType().Equals(typeof (Exception)))
+                {
+                    throw new System.Exception("Threw the wrong exception");
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
product/support/unit/unit.csproj
@@ -48,20 +48,35 @@
     <Reference Include="System.Xml" />
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="AssertionExtensions.cs" />
     <Compile Include="client\presenters\AddFamilyMemberPresenterSpecs.cs" />
     <Compile Include="Helpers.cs" />
     <Compile Include="client\presenters\WpfCommandBuilderSpecs.cs" />
     <Compile Include="Mocking.cs" />
+    <Compile Include="server\domain\accounting\BOEDSpecs.cs" />
+    <Compile Include="server\domain\accounting\CurrencySpecs.cs" />
+    <Compile Include="server\domain\accounting\DetailAccountSpecs.cs" />
+    <Compile Include="server\domain\accounting\QuantitySpecs.cs" />
+    <Compile Include="server\domain\accounting\SummaryAccountSpecs.cs" />
+    <Compile Include="server\domain\accounting\TransactionSpecs.cs" />
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\..\client\client.ui\client.csproj">
       <Project>{81E2CF6C-4D61-442E-8086-BF1E017C7041}</Project>
       <Name>client %28client\client%29</Name>
     </ProjectReference>
+    <ProjectReference Include="..\..\client\server\server.csproj">
+      <Project>{4E60988E-1A43-4807-8CEC-4E13F63DE363}</Project>
+      <Name>server</Name>
+    </ProjectReference>
     <ProjectReference Include="..\..\commons\infrastructure\infrastructure.csproj">
       <Project>{AA5EEED9-4531-45F7-AFCD-AD9717D2E405}</Project>
       <Name>infrastructure</Name>
     </ProjectReference>
+    <ProjectReference Include="..\..\commons\utility\utility.csproj">
+      <Project>{DD8FD29E-7424-415C-9BA3-7D9F6ECBA161}</Project>
+      <Name>utility</Name>
+    </ProjectReference>
   </ItemGroup>
   <ItemGroup>
     <Folder Include="Properties\" />