Commit 2e7be8b

unknown <mo@.(none)>
2009-09-06 03:28:40
got the progress bar to report the progress of each command and query.
1 parent 09652f2
Changed files (98)
build
product
Boot
Presentation
Service
build/lib/app/gorilla/gorilla.commons.infrastructure.dll
Binary file
build/lib/app/gorilla/gorilla.commons.infrastructure.thirdparty.dll
Binary file
build/lib/app/gorilla/gorilla.commons.utility.dll
Binary file
product/Boot/boot/container/registration/proxy_configuration/NotifyProgressInterceptor.cs
@@ -0,0 +1,27 @@
+using Castle.Core.Interceptor;
+using MoMoney.Presentation.Model.messages;
+using MoMoney.Service.Infrastructure.Eventing;
+
+namespace MoMoney.boot.container.registration.proxy_configuration
+{
+    public interface INotifyProgressInterceptor : IInterceptor
+    {
+    }
+
+    public class NotifyProgressInterceptor : INotifyProgressInterceptor
+    {
+        readonly IEventAggregator broker;
+
+        public NotifyProgressInterceptor(IEventAggregator broker)
+        {
+            this.broker = broker;
+        }
+
+        public void Intercept(IInvocation invocation)
+        {
+            broker.publish(new StartedRunningCommand(invocation.TargetType.Name));
+            invocation.Proceed();
+            broker.publish(new FinishedRunningCommand(invocation.TargetType.Name));
+        }
+    }
+}
\ No newline at end of file
product/Boot/boot/container/registration/proxy_configuration/ServiceLayerConfiguration.cs
@@ -9,6 +9,7 @@ namespace MoMoney.boot.container.registration.proxy_configuration
         public void configure(IProxyBuilder<T> item)
         {
             item.add_interceptor(Lazy.load<IUnitOfWorkInterceptor>()).intercept_all();
+            item.add_interceptor(Lazy.load<INotifyProgressInterceptor>()).intercept_all();
 
             //item
             //    .add_interceptor(
product/Boot/boot/container/registration/proxy_configuration/UnitOfWorkInterceptor.cs
@@ -1,7 +1,7 @@
 using Castle.Core.Interceptor;
-using Gorilla.Commons.Infrastructure.Eventing;
 using Gorilla.Commons.Utility.Core;
 using MoMoney.Service.Contracts.Infrastructure.Transactions;
+using MoMoney.Service.Infrastructure.Eventing;
 using MoMoney.Service.Infrastructure.Transactions;
 
 namespace MoMoney.boot.container.registration.proxy_configuration
product/Boot/boot/container/registration/wire_up_the_infrastructure_in_to_the.cs
@@ -2,13 +2,14 @@ using System.Collections;
 using System.ComponentModel;
 using System.Deployment.Application;
 using Gorilla.Commons.Infrastructure;
-using Gorilla.Commons.Infrastructure.Eventing;
 using Gorilla.Commons.Infrastructure.Registries;
 using Gorilla.Commons.Infrastructure.Threading;
 using Gorilla.Commons.Infrastructure.Transactions;
 using Gorilla.Commons.Utility.Core;
 using MoMoney.Presentation.Model.Projects;
 using MoMoney.Presentation.Presenters.Commands;
+using MoMoney.Service.Infrastructure.Eventing;
+using MoMoney.Service.Infrastructure.Threading;
 using MoMoney.Service.Infrastructure.Updating;
 using MoMoney.Tasks.infrastructure.updating;
 
product/Boot/boot/container/registration/wire_up_the_services_in_to_the.cs
@@ -20,9 +20,6 @@ namespace MoMoney.boot.container.registration
 
         public void run()
         {
-            registry.proxy<IGetTheCurrentCustomerQuery, ServiceLayerConfiguration<IGetTheCurrentCustomerQuery>>(
-                () => new GetTheCurrentCustomerQuery(Lazy.load<IAccountHolderRepository>()));
-
             wire_up_queries();
             wire_up_the_commands();
         }
@@ -39,6 +36,8 @@ namespace MoMoney.boot.container.registration
                 () =>
                 new GetAllIncomeQuery(Lazy.load<IIncomeRepository>(),
                                       Lazy.load<IMapper<IIncome, IncomeInformationDTO>>()));
+            registry.proxy<IGetTheCurrentCustomerQuery, ServiceLayerConfiguration<IGetTheCurrentCustomerQuery>>(
+                () => new GetTheCurrentCustomerQuery(Lazy.load<IAccountHolderRepository>()));
         }
 
         void wire_up_the_commands()
product/Boot/boot/display_the_splash_screen.cs
@@ -1,5 +1,5 @@
 using System;
-using MoMoney.Presentation.Presenters.Startup;
+using MoMoney.Presentation.Presenters;
 using MoMoney.Utility.Core;
 
 namespace MoMoney.boot
product/Boot/boot/global_error_handling.cs
@@ -1,11 +1,11 @@
 using System;
 using System.Windows.Forms;
 using Gorilla.Commons.Infrastructure.Container;
-using Gorilla.Commons.Infrastructure.Eventing;
 using Gorilla.Commons.Infrastructure.Logging;
 using Gorilla.Commons.Utility.Core;
 using Gorilla.Commons.Utility.Extensions;
 using MoMoney.Presentation.Model.messages;
+using MoMoney.Service.Infrastructure.Eventing;
 
 namespace MoMoney.boot
 {
product/Boot/boot/WindowsFormsApplication.cs
@@ -7,14 +7,14 @@ using System.Security.Principal;
 using System.Threading;
 using System.Windows.Forms;
 using Gorilla.Commons.Infrastructure.Container;
-using Gorilla.Commons.Infrastructure.Eventing;
 using Gorilla.Commons.Infrastructure.Logging;
 using Gorilla.Commons.Infrastructure.Threading;
 using Gorilla.Commons.Utility.Core;
 using Gorilla.Commons.Utility.Extensions;
 using MoMoney.boot.container;
 using MoMoney.Presentation.Model.messages;
-using MoMoney.Presentation.Presenters.Startup;
+using MoMoney.Presentation.Presenters;
+using MoMoney.Service.Infrastructure.Eventing;
 using MoMoney.windows.ui;
 
 namespace MoMoney.boot
product/Boot/Modules/ApplicationMenuModule.cs
@@ -1,8 +1,8 @@
-using Gorilla.Commons.Infrastructure.Eventing;
 using MoMoney.Presentation.Model.Menu;
 using MoMoney.Presentation.Model.messages;
 using MoMoney.Presentation.Presenters;
 using MoMoney.Presentation.Presenters.Menu;
+using MoMoney.Service.Infrastructure.Eventing;
 
 namespace MoMoney.Modules
 {
product/Boot/Modules/DatabaseModule.cs
@@ -1,5 +1,5 @@
-using Gorilla.Commons.Infrastructure.Eventing;
 using MoMoney.DataAccess;
+using MoMoney.Service.Infrastructure.Eventing;
 
 namespace MoMoney.Modules
 {
product/Boot/Modules/GettingStartedModule.cs
@@ -1,8 +1,8 @@
-using Gorilla.Commons.Infrastructure.Eventing;
 using MoMoney.Presentation;
 using MoMoney.Presentation.Model.messages;
 using MoMoney.Presentation.Presenters;
 using MoMoney.Presentation.Presenters.Shell;
+using MoMoney.Service.Infrastructure.Eventing;
 
 namespace MoMoney.Modules
 {
product/Boot/Modules/GettingStartedModuleSpecs.cs
@@ -1,7 +1,7 @@
 using developwithpassion.bdd.contexts;
-using Gorilla.Commons.Infrastructure.Eventing;
 using Gorilla.Commons.Testing;
 using MoMoney.Presentation.Presenters;
+using MoMoney.Service.Infrastructure.Eventing;
 
 namespace MoMoney.Modules
 {
product/Boot/Modules/IApplicationMenuModule.cs
@@ -1,6 +1,6 @@
-using Gorilla.Commons.Infrastructure.Eventing;
 using MoMoney.Presentation;
 using MoMoney.Presentation.Model.messages;
+using MoMoney.Service.Infrastructure.Eventing;
 
 namespace MoMoney.Modules
 {
product/Boot/Modules/IMainMenuModule.cs
@@ -1,6 +1,6 @@
-using Gorilla.Commons.Infrastructure.Eventing;
 using MoMoney.Presentation;
 using MoMoney.Presentation.Model.messages;
+using MoMoney.Service.Infrastructure.Eventing;
 
 namespace MoMoney.Modules
 {
product/Boot/Modules/INavigationModule.cs
@@ -1,6 +1,6 @@
-using Gorilla.Commons.Infrastructure.Eventing;
 using MoMoney.Presentation;
 using MoMoney.Presentation.Model.messages;
+using MoMoney.Service.Infrastructure.Eventing;
 
 namespace MoMoney.Modules
 {
product/Boot/Modules/IToolbarModule.cs
@@ -1,6 +1,6 @@
-using Gorilla.Commons.Infrastructure.Eventing;
 using MoMoney.Presentation;
 using MoMoney.Presentation.Model.messages;
+using MoMoney.Service.Infrastructure.Eventing;
 
 namespace MoMoney.Modules
 {
product/Boot/Modules/MainMenuModule.cs
@@ -1,6 +1,6 @@
-using Gorilla.Commons.Infrastructure.Eventing;
 using MoMoney.Presentation.Model.messages;
 using MoMoney.Presentation.Presenters;
+using MoMoney.Service.Infrastructure.Eventing;
 
 namespace MoMoney.Modules
 {
product/Boot/Modules/NavigationModule.cs
@@ -1,7 +1,7 @@
-using Gorilla.Commons.Infrastructure.Eventing;
 using MoMoney.Presentation.Model.messages;
 using MoMoney.Presentation.Presenters;
 using MoMoney.Presentation.Presenters.Navigation;
+using MoMoney.Service.Infrastructure.Eventing;
 
 namespace MoMoney.Modules
 {
product/Boot/Modules/ToolbarModule.cs
@@ -1,8 +1,8 @@
-using Gorilla.Commons.Infrastructure.Eventing;
 using MoMoney.Presentation.Model.Menu;
 using MoMoney.Presentation.Model.messages;
 using MoMoney.Presentation.Presenters;
 using MoMoney.Presentation.Presenters.Shell;
+using MoMoney.Service.Infrastructure.Eventing;
 
 namespace MoMoney.Modules
 {
product/Boot/Boot.csproj
@@ -143,6 +143,7 @@
     <Compile Include="boot\container\registration\proxy_configuration\InterceptingFilterFactorySpecs.cs" />
     <Compile Include="boot\container\registration\proxy_configuration\InterceptingFilterSpecs.cs" />
     <Compile Include="boot\container\registration\proxy_configuration\NoConfiguration.cs" />
+    <Compile Include="boot\container\registration\proxy_configuration\NotifyProgressInterceptor.cs" />
     <Compile Include="boot\container\registration\proxy_configuration\SecuringProxy.cs" />
     <Compile Include="boot\container\registration\proxy_configuration\SecuringProxySpecs.cs" />
     <Compile Include="boot\container\registration\proxy_configuration\ServiceLayerConfiguration.cs" />
product/Presentation/Model/Menu/File/ExitCommand.cs
@@ -1,7 +1,7 @@
-using Gorilla.Commons.Infrastructure.Eventing;
 using Gorilla.Commons.Utility.Core;
 using MoMoney.Presentation.Core;
 using MoMoney.Presentation.Model.messages;
+using MoMoney.Service.Infrastructure.Eventing;
 
 namespace MoMoney.Presentation.Model.Menu.File.Commands
 {
product/Presentation/Model/Menu/File/ExitCommandSpecs.cs
@@ -1,8 +1,8 @@
 using developwithpassion.bdd.contexts;
-using Gorilla.Commons.Infrastructure.Eventing;
 using Gorilla.Commons.Testing;
 using MoMoney.Presentation.Core;
 using MoMoney.Presentation.Model.messages;
+using MoMoney.Service.Infrastructure.Eventing;
 
 namespace MoMoney.Presentation.Model.Menu.File.Commands
 {
product/Presentation/Model/Menu/MenuItemBuilder.cs
@@ -1,10 +1,10 @@
 using System;
 using Gorilla.Commons.Infrastructure.Container;
-using Gorilla.Commons.Infrastructure.Eventing;
 using Gorilla.Commons.Infrastructure.Threading;
 using Gorilla.Commons.Utility.Core;
 using MoMoney.Presentation.Winforms.Keyboard;
 using MoMoney.Presentation.Winforms.Resources;
+using MoMoney.Service.Infrastructure.Eventing;
 
 namespace MoMoney.Presentation.Model.Menu
 {
product/Presentation/Model/Menu/ToolBarItemBuilder.cs
@@ -1,10 +1,10 @@
 using System;
 using System.Windows.Forms;
 using Gorilla.Commons.Infrastructure.Container;
-using Gorilla.Commons.Infrastructure.Eventing;
 using Gorilla.Commons.Infrastructure.Threading;
 using Gorilla.Commons.Utility.Core;
 using MoMoney.Presentation.Winforms.Resources;
+using MoMoney.Service.Infrastructure.Eventing;
 
 namespace MoMoney.Presentation.Model.Menu
 {
product/Presentation/Model/Messages/ClosingProjectEvent.cs
@@ -1,4 +1,4 @@
-using Gorilla.Commons.Infrastructure.Eventing;
+using MoMoney.Service.Infrastructure.Eventing;
 
 namespace MoMoney.Presentation.Model.messages
 {
product/Presentation/Model/Messages/ClosingTheApplication.cs
@@ -1,4 +1,4 @@
-using Gorilla.Commons.Infrastructure.Eventing;
+using MoMoney.Service.Infrastructure.Eventing;
 
 namespace MoMoney.Presentation.Model.messages
 {
product/Presentation/Model/Messages/FinishedRunningCommand.cs
@@ -0,0 +1,14 @@
+using MoMoney.Service.Infrastructure.Eventing;
+
+namespace MoMoney.Presentation.Model.messages
+{
+    public class FinishedRunningCommand : IEvent
+    {
+        public FinishedRunningCommand(object running_command)
+        {
+            completed_action = running_command;
+        }
+
+        public object completed_action { get; private set; }
+    }
+}
\ No newline at end of file
product/Presentation/Model/Messages/NewProjectOpened.cs
@@ -1,4 +1,4 @@
-using Gorilla.Commons.Infrastructure.Eventing;
+using MoMoney.Service.Infrastructure.Eventing;
 
 namespace MoMoney.Presentation.Model.messages
 {
product/Presentation/Model/Messages/SavedChangesEvent.cs
@@ -1,4 +1,4 @@
-using Gorilla.Commons.Infrastructure.Eventing;
+using MoMoney.Service.Infrastructure.Eventing;
 
 namespace MoMoney.Presentation.Model.messages
 {
product/Presentation/Model/Messages/StartedRunningCommand.cs
@@ -0,0 +1,14 @@
+using MoMoney.Service.Infrastructure.Eventing;
+
+namespace MoMoney.Presentation.Model.messages
+{
+    public class StartedRunningCommand : IEvent
+    {
+        public StartedRunningCommand(object running_command)
+        {
+            running_action = running_command;
+        }
+
+        public object running_action { get; private set; }
+    }
+}
\ No newline at end of file
product/Presentation/Model/Messages/UnhandledErrorOccurred.cs
@@ -1,5 +1,5 @@
 using System;
-using Gorilla.Commons.Infrastructure.Eventing;
+using MoMoney.Service.Infrastructure.Eventing;
 
 namespace MoMoney.Presentation.Model.messages
 {
product/Presentation/Model/Messages/UnsavedChangesEvent.cs
@@ -1,4 +1,4 @@
-using Gorilla.Commons.Infrastructure.Eventing;
+using MoMoney.Service.Infrastructure.Eventing;
 
 namespace MoMoney.Presentation.Model.messages
 {
product/Presentation/Model/Projects/ProjectController.cs
@@ -1,10 +1,10 @@
-using Gorilla.Commons.Infrastructure.Eventing;
 using Gorilla.Commons.Infrastructure.FileSystem;
 using Gorilla.Commons.Infrastructure.Logging;
 using Gorilla.Commons.Utility.Core;
 using Gorilla.Commons.Utility.Extensions;
 using MoMoney.Presentation.Model.messages;
 using MoMoney.Service.Contracts.Infrastructure;
+using MoMoney.Service.Infrastructure.Eventing;
 using MoMoney.Service.Infrastructure.Transactions;
 
 namespace MoMoney.Presentation.Model.Projects
product/Presentation/Model/Projects/ProjectControllerSpecs.cs
@@ -1,11 +1,11 @@
 using System;
 using developwithpassion.bdd.contexts;
-using Gorilla.Commons.Infrastructure.Eventing;
 using Gorilla.Commons.Infrastructure.FileSystem;
 using Gorilla.Commons.Testing;
 using Gorilla.Commons.Utility.Extensions;
 using MoMoney.Presentation.Model.messages;
 using MoMoney.Service.Contracts.Infrastructure;
+using MoMoney.Service.Infrastructure.Eventing;
 using MoMoney.Service.Infrastructure.Transactions;
 
 namespace MoMoney.Presentation.Model.Projects
product/Presentation/Presenters/ApplicationShellPresenter.cs
@@ -1,8 +1,8 @@
-using Gorilla.Commons.Infrastructure.Eventing;
 using MoMoney.Presentation.Core;
 using MoMoney.Presentation.Model.Menu.File.Commands;
 using MoMoney.Presentation.Model.messages;
 using MoMoney.Presentation.Views;
+using MoMoney.Service.Infrastructure.Eventing;
 
 namespace MoMoney.Presentation.Presenters.Shell
 {
product/Presentation/Presenters/display_the_splash_screen.cs
@@ -1,6 +1,6 @@
 using System;
-using Gorilla.Commons.Infrastructure.Threading;
 using MoMoney.Presentation.Views.Startup;
+using MoMoney.Service.Infrastructure.Threading;
 
 namespace MoMoney.Presentation.Presenters.Startup
 {
product/Presentation/Presenters/GettingStartedPresenterSpecs.cs
@@ -1,7 +1,7 @@
 using developwithpassion.bdd.contexts;
-using Gorilla.Commons.Infrastructure.Eventing;
 using Gorilla.Commons.Testing;
 using MoMoney.Presentation.Views.Shell;
+using MoMoney.Service.Infrastructure.Eventing;
 
 namespace MoMoney.Presentation.Presenters.Shell
 {
product/Presentation/Presenters/hide_the_splash_screen.cs
@@ -1,6 +1,6 @@
 using System;
-using Gorilla.Commons.Infrastructure.Threading;
 using MoMoney.Presentation.Views.Startup;
+using MoMoney.Service.Infrastructure.Threading;
 
 namespace MoMoney.Presentation.Presenters.Startup
 {
product/Presentation/Presenters/NotificationIconPresenter.cs
@@ -1,8 +1,8 @@
 using System.Net.NetworkInformation;
-using Gorilla.Commons.Infrastructure.Eventing;
 using MoMoney.Presentation.Model.messages;
 using MoMoney.Presentation.Views.Shell;
 using MoMoney.Presentation.Winforms.Resources;
+using MoMoney.Service.Infrastructure.Eventing;
 
 namespace MoMoney.Presentation.Presenters.Shell
 {
product/Presentation/Presenters/NotificationIconPresenterSpecs.cs
@@ -1,8 +1,8 @@
 using developwithpassion.bdd.contexts;
-using Gorilla.Commons.Infrastructure.Eventing;
 using Gorilla.Commons.Testing;
 using MoMoney.Presentation.Views.Shell;
 using MoMoney.Presentation.Winforms.Resources;
+using MoMoney.Service.Infrastructure.Eventing;
 
 namespace MoMoney.Presentation.Presenters.Shell
 {
product/Presentation/Presenters/RestartCommand.cs
@@ -1,7 +1,7 @@
-using Gorilla.Commons.Infrastructure.Eventing;
 using Gorilla.Commons.Utility.Core;
 using MoMoney.Presentation.Core;
 using MoMoney.Presentation.Model.messages;
+using MoMoney.Service.Infrastructure.Eventing;
 
 namespace MoMoney.Presentation.Presenters.Commands
 {
product/Presentation/Presenters/SplashScreenPresenter.cs
@@ -1,9 +1,11 @@
 using Gorilla.Commons.Infrastructure.Threading;
+using MoMoney.Presentation.Presenters.Startup;
 using MoMoney.Presentation.Views.Startup;
 using MoMoney.Presentation.Winforms.Views;
+using MoMoney.Service.Infrastructure.Threading;
 using MoMoney.Utility.Core;
 
-namespace MoMoney.Presentation.Presenters.Startup
+namespace MoMoney.Presentation.Presenters
 {
     public interface ISplashScreenPresenter : IDisposableCommand, ITimerClient
     {
product/Presentation/Presenters/SplashScreenPresenterSpecs.cs
@@ -1,8 +1,8 @@
 using System;
 using developwithpassion.bdd.contexts;
-using Gorilla.Commons.Infrastructure.Threading;
 using Gorilla.Commons.Testing;
 using MoMoney.Presentation.Views.Startup;
+using MoMoney.Service.Infrastructure.Threading;
 
 namespace MoMoney.Presentation.Presenters.Startup
 {
product/Presentation/Presenters/StatusBarPresenter.cs
@@ -1,16 +1,21 @@
-using Gorilla.Commons.Infrastructure.Eventing;
+using System;
 using Gorilla.Commons.Utility;
 using Gorilla.Commons.Utility.Extensions;
 using MoMoney.Presentation.Model.messages;
-using MoMoney.Presentation.Views.Shell;
+using MoMoney.Presentation.Views;
 using MoMoney.Presentation.Winforms.Resources;
+using MoMoney.Service.Infrastructure.Eventing;
+using MoMoney.Service.Infrastructure.Threading;
 
-namespace MoMoney.Presentation.Presenters.Shell
+namespace MoMoney.Presentation.Presenters
 {
     public interface IStatusBarPresenter : IModule,
                                            IEventSubscriber<SavedChangesEvent>,
                                            IEventSubscriber<NewProjectOpened>,
                                            IEventSubscriber<ClosingTheApplication>,
+                                           IEventSubscriber<UnsavedChangesEvent>,
+                                           IEventSubscriber<StartedRunningCommand>,
+                                           IEventSubscriber<FinishedRunningCommand>,
                                            IEventSubscriber<ClosingProjectEvent>
     {
     }
@@ -19,36 +24,57 @@ namespace MoMoney.Presentation.Presenters.Shell
     {
         readonly IStatusBarView view;
         readonly IEventAggregator broker;
+        readonly ITimer timer;
 
-        public StatusBarPresenter(IStatusBarView view, IEventAggregator broker)
+        public StatusBarPresenter(IStatusBarView view, IEventAggregator broker, ITimer timer)
         {
             this.view = view;
             this.broker = broker;
+            this.timer = timer;
         }
 
         public void run()
         {
             broker.subscribe(this);
+            view.display(ApplicationIcons.blue_circle, "...");
         }
 
         public void notify(SavedChangesEvent message)
         {
-            view.display(ApplicationIcons.ApplicationReady, "Last Saved: {0}".formatted_using(Clock.now()));
+            view.display(ApplicationIcons.floppy_disk, "Last Saved: {0}".formatted_using(Clock.now()));
         }
 
         public void notify(NewProjectOpened message)
         {
-            view.display(ApplicationIcons.ApplicationReady, "Ready");
+            view.display(ApplicationIcons.green_circle, "Ready");
         }
 
         public void notify(ClosingTheApplication message)
         {
-            view.display(ApplicationIcons.Empty, "Good Bye!");
+            view.display(ApplicationIcons.hour_glass, "Good Bye!");
         }
 
         public void notify(ClosingProjectEvent message)
         {
-            view.display(ApplicationIcons.ApplicationReady, "Ready");
+            view.display(ApplicationIcons.grey_circle, "Closed");
+        }
+
+        public void notify(UnsavedChangesEvent message)
+        {
+            view.display(ApplicationIcons.red_circle, "Don't forget to save your work...");
+        }
+
+        public void notify(StartedRunningCommand message)
+        {
+            view.display(ApplicationIcons.hour_glass, "Running... {0}".formatted_using(message.running_action));
+            timer.start_notifying(view, new TimeSpan(1));
+        }
+
+        public void notify(FinishedRunningCommand message)
+        {
+            view.display(ApplicationIcons.green_circle, "Finished... {0}".formatted_using(message.completed_action));
+            timer.stop_notifying(view);
+            view.reset_progress_bar();
         }
     }
 }
\ No newline at end of file
product/Presentation/Presenters/StatusBarPresenterSpecs.cs
@@ -1,17 +1,17 @@
 using developwithpassion.bdd.contexts;
-using Gorilla.Commons.Infrastructure.Eventing;
 using Gorilla.Commons.Testing;
 using MoMoney.Presentation.Model.messages;
-using MoMoney.Presentation.Views.Shell;
+using MoMoney.Presentation.Views;
 using MoMoney.Presentation.Winforms.Resources;
+using MoMoney.Service.Infrastructure.Eventing;
 
-namespace MoMoney.Presentation.Presenters.Shell
+namespace MoMoney.Presentation.Presenters
 {
     [Concern(typeof (StatusBarPresenter))]
     public class when_initializing_the_status_bar : concerns_for<IStatusBarPresenter, StatusBarPresenter>
     {
         it should_display_a_ready_message =
-            () => view.was_told_to(v => v.display(ApplicationIcons.ApplicationReady, "Ready"));
+            () => view.was_told_to(v => v.display(ApplicationIcons.green_circle, "Ready"));
 
         context c = () =>
                         {
@@ -21,11 +21,6 @@ namespace MoMoney.Presentation.Presenters.Shell
 
         because b = () => sut.notify(new NewProjectOpened(""));
 
-        //public override IStatusBarPresenter create_sut()
-        //{
-        //    return new StatusBarPresenter(view, broker);
-        //}
-
         static IStatusBarView view;
         static IEventAggregator broker;
     }
product/Presentation/Presenters/TaskTrayPresenter.cs
@@ -1,6 +1,6 @@
-using Gorilla.Commons.Infrastructure.Eventing;
 using MoMoney.Presentation.Model.messages;
 using MoMoney.Presentation.Views.Shell;
+using MoMoney.Service.Infrastructure.Eventing;
 
 namespace MoMoney.Presentation.Presenters.Shell
 {
product/Presentation/Presenters/TitleBarPresenter.cs
@@ -1,8 +1,8 @@
-using Gorilla.Commons.Infrastructure.Eventing;
 using Gorilla.Commons.Infrastructure.Logging;
 using MoMoney.Presentation.Model.messages;
 using MoMoney.Presentation.Model.Projects;
 using MoMoney.Presentation.Views;
+using MoMoney.Service.Infrastructure.Eventing;
 
 namespace MoMoney.Presentation.Presenters.Shell
 {
product/Presentation/Presenters/TitleBarPresenterSpecs.cs
@@ -1,9 +1,9 @@
 using developwithpassion.bdd.contexts;
-using Gorilla.Commons.Infrastructure.Eventing;
 using Gorilla.Commons.Testing;
 using MoMoney.Presentation.Model.messages;
 using MoMoney.Presentation.Model.Projects;
 using MoMoney.Presentation.Views;
+using MoMoney.Service.Infrastructure.Eventing;
 
 namespace MoMoney.Presentation.Presenters.Shell
 {
product/Presentation/Presenters/UnhandledErrorPresenter.cs
@@ -1,8 +1,8 @@
-using Gorilla.Commons.Infrastructure.Eventing;
 using MoMoney.Presentation.Core;
 using MoMoney.Presentation.Model.messages;
 using MoMoney.Presentation.Presenters.Commands;
 using MoMoney.Presentation.Views.Shell;
+using MoMoney.Service.Infrastructure.Eventing;
 
 namespace MoMoney.Presentation.Presenters.Shell
 {
product/Presentation/Presenters/UnhandledErrorPresenterSpecs.cs
@@ -1,9 +1,9 @@
 using System;
 using developwithpassion.bdd.contexts;
-using Gorilla.Commons.Infrastructure.Eventing;
 using Gorilla.Commons.Testing;
 using MoMoney.Presentation.Model.messages;
 using MoMoney.Presentation.Views.Shell;
+using MoMoney.Service.Infrastructure.Eventing;
 
 namespace MoMoney.Presentation.Presenters.Shell
 {
product/Presentation/Views/IStatusBarView.cs
@@ -1,9 +1,11 @@
+using Gorilla.Commons.Infrastructure.Threading;
 using MoMoney.Presentation.Winforms.Resources;
 
-namespace MoMoney.Presentation.Views.Shell
+namespace MoMoney.Presentation.Views
 {
-    public interface IStatusBarView
+    public interface IStatusBarView : ITimerClient
     {
         void display(HybridIcon icon_to_display, string text_to_display);
+        void reset_progress_bar();
     }
 }
\ No newline at end of file
product/Presentation/Winforms/Resources/ApplicationIcons.cs
@@ -9,7 +9,6 @@ namespace MoMoney.Presentation.Winforms.Resources
 
         static public readonly ApplicationIcon Application = new ApplicationIcon("mokhan.ico", x => add(x));
         static public readonly ApplicationIcon FileExplorer = new ApplicationIcon("binoculars.ico", x => add(x));
-        static public readonly HybridIcon ApplicationReady = new HybridIcon("circle_green.ico", x => add(x));
         static public readonly ApplicationIcon AddIncome = new ApplicationIcon("generic_document.ico", x => add(x));
         static public readonly HybridIcon NewProject = new HybridIcon("generic_document.ico", x => add(x));
         static public readonly HybridIcon OpenProject = new HybridIcon("foldergreen.ico", x => add(x));
@@ -28,6 +27,17 @@ namespace MoMoney.Presentation.Winforms.Resources
         static public readonly HybridIcon ViewAllIncome = new HybridIcon("search.ico", x => add(x));
         static public readonly HybridIcon AddBillPayment = new HybridIcon("plus__orange.ico", x => add(x));
         static public readonly HybridIcon ViewAllBillPayments = new HybridIcon("search.ico", x => add(x));
+        static public readonly HybridIcon Home = new HybridIcon("home.ico", x => add(x));
+
+        static public readonly HybridIcon hour_glass = new HybridIcon("hourglass.ico", x => add(x));
+        static public readonly HybridIcon green_circle = new HybridIcon("circle_green.ico", x => add(x));
+        static public readonly HybridIcon blue_circle = new HybridIcon("circle_blue.ico", x => add(x));
+        static public readonly HybridIcon grey_circle = new HybridIcon("circle_grey.ico", x => add(x));
+        static public readonly HybridIcon orange_circle = new HybridIcon("circle_orange.ico", x => add(x));
+        static public readonly HybridIcon red_circle = new HybridIcon("circle_red.ico", x => add(x));
+        static public readonly HybridIcon yellow_circle = new HybridIcon("circle_yellow.ico", x => add(x));
+
+        static public readonly HybridIcon floppy_disk = new HybridIcon("floppydisk.ico", x => add(x));
 
         static public IEnumerable<ApplicationIcon> all()
         {
product/Presentation/Winforms/Views/AddBillPaymentView.cs
@@ -7,6 +7,7 @@ using MoMoney.Presentation.Views.billing;
 using MoMoney.Presentation.Views.Core;
 using MoMoney.Presentation.Winforms.Helpers;
 using MoMoney.Presentation.Winforms.Krypton;
+using MoMoney.Presentation.Winforms.Resources;
 
 namespace MoMoney.Presentation.Winforms.Views
 {
@@ -18,7 +19,8 @@ namespace MoMoney.Presentation.Winforms.Views
         public AddBillPaymentView()
         {
             InitializeComponent();
-            titled("Add Bill Payment");
+            titled("Add Bill Payment")
+                .icon(ApplicationIcons.AddBillPayment);
             ux_submit_button.Click += (sender, e) => submit_clicked(e);
             companies_list = ux_company_names.create_for<CompanyDTO>();
         }
product/Presentation/Winforms/Views/AddCompanyView.cs
@@ -20,7 +20,8 @@ namespace MoMoney.Presentation.Winforms.Views
         public AddCompanyView()
         {
             InitializeComponent();
-            titled("Add A Company");
+            titled("Add A Company")
+                .icon(ApplicationIcons.AddCompany);
             dto = new RegisterNewCompany();
 
             listView1.View = View.LargeIcon;
product/Presentation/Winforms/Views/AddCompanyView.Designer.cs
@@ -30,34 +30,26 @@ namespace MoMoney.Presentation.Winforms.Views
         {
             System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AddCompanyView));
             this.kryptonHeaderGroup1 = new ComponentFactory.Krypton.Toolkit.KryptonHeaderGroup();
+            this.ux_companys_listing = new ComponentFactory.Krypton.Toolkit.KryptonDataGridView();
+            this.kryptonSplitContainer2 = new ComponentFactory.Krypton.Toolkit.KryptonSplitContainer();
+            this.kryptonGroup1 = new ComponentFactory.Krypton.Toolkit.KryptonGroup();
+            this.kryptonGroup2 = new ComponentFactory.Krypton.Toolkit.KryptonGroup();
             this.kryptonSplitContainer1 = new ComponentFactory.Krypton.Toolkit.KryptonSplitContainer();
             this.listView1 = new System.Windows.Forms.ListView();
             this.ux_submit_button = new ComponentFactory.Krypton.Toolkit.KryptonButton();
-            this.kryptonLabel1 = new ComponentFactory.Krypton.Toolkit.KryptonLabel();
             this.ux_company_name = new ComponentFactory.Krypton.Toolkit.KryptonTextBox();
             this.ux_cancel_button = new System.Windows.Forms.Button();
-            this.kryptonSplitContainer2 = new ComponentFactory.Krypton.Toolkit.KryptonSplitContainer();
-            this.kryptonHeader1 = new ComponentFactory.Krypton.Toolkit.KryptonHeader();
-            this.ux_companys_listing = new ComponentFactory.Krypton.Toolkit.KryptonDataGridView();
-            this.kryptonGroup1 = new ComponentFactory.Krypton.Toolkit.KryptonGroup();
-            this.kryptonGroup2 = new ComponentFactory.Krypton.Toolkit.KryptonGroup();
+            this.kryptonLabel1 = new ComponentFactory.Krypton.Toolkit.KryptonLabel();
             ((System.ComponentModel.ISupportInitialize)(this.kryptonHeaderGroup1)).BeginInit();
             ((System.ComponentModel.ISupportInitialize)(this.kryptonHeaderGroup1.Panel)).BeginInit();
             this.kryptonHeaderGroup1.Panel.SuspendLayout();
             this.kryptonHeaderGroup1.SuspendLayout();
-            ((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer1)).BeginInit();
-            ((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer1.Panel1)).BeginInit();
-            this.kryptonSplitContainer1.Panel1.SuspendLayout();
-            ((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer1.Panel2)).BeginInit();
-            this.kryptonSplitContainer1.Panel2.SuspendLayout();
-            this.kryptonSplitContainer1.SuspendLayout();
+            ((System.ComponentModel.ISupportInitialize)(this.ux_companys_listing)).BeginInit();
             ((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer2)).BeginInit();
             ((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer2.Panel1)).BeginInit();
-            this.kryptonSplitContainer2.Panel1.SuspendLayout();
             ((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer2.Panel2)).BeginInit();
             this.kryptonSplitContainer2.Panel2.SuspendLayout();
             this.kryptonSplitContainer2.SuspendLayout();
-            ((System.ComponentModel.ISupportInitialize)(this.ux_companys_listing)).BeginInit();
             ((System.ComponentModel.ISupportInitialize)(this.kryptonGroup1)).BeginInit();
             ((System.ComponentModel.ISupportInitialize)(this.kryptonGroup1.Panel)).BeginInit();
             this.kryptonGroup1.Panel.SuspendLayout();
@@ -66,19 +58,26 @@ namespace MoMoney.Presentation.Winforms.Views
             ((System.ComponentModel.ISupportInitialize)(this.kryptonGroup2.Panel)).BeginInit();
             this.kryptonGroup2.Panel.SuspendLayout();
             this.kryptonGroup2.SuspendLayout();
+            ((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer1)).BeginInit();
+            ((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer1.Panel1)).BeginInit();
+            this.kryptonSplitContainer1.Panel1.SuspendLayout();
+            ((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer1.Panel2)).BeginInit();
+            this.kryptonSplitContainer1.Panel2.SuspendLayout();
+            this.kryptonSplitContainer1.SuspendLayout();
             this.SuspendLayout();
             // 
             // kryptonHeaderGroup1
             // 
             this.kryptonHeaderGroup1.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.kryptonHeaderGroup1.GroupBackStyle = ComponentFactory.Krypton.Toolkit.PaletteBackStyle.FormMain;
             this.kryptonHeaderGroup1.Location = new System.Drawing.Point(0, 0);
-            this.kryptonHeaderGroup1.Margin = new System.Windows.Forms.Padding(4);
             this.kryptonHeaderGroup1.Name = "kryptonHeaderGroup1";
+            this.kryptonHeaderGroup1.PaletteMode = ComponentFactory.Krypton.Toolkit.PaletteMode.SparkleBlue;
             // 
             // kryptonHeaderGroup1.Panel
             // 
             this.kryptonHeaderGroup1.Panel.Controls.Add(this.kryptonSplitContainer1);
-            this.kryptonHeaderGroup1.Size = new System.Drawing.Size(1037, 876);
+            this.kryptonHeaderGroup1.Size = new System.Drawing.Size(778, 712);
             this.kryptonHeaderGroup1.TabIndex = 0;
             this.kryptonHeaderGroup1.Text = "Add Company";
             this.kryptonHeaderGroup1.ValuesPrimary.Description = "";
@@ -88,42 +87,102 @@ namespace MoMoney.Presentation.Winforms.Views
             this.kryptonHeaderGroup1.ValuesSecondary.Heading = "Description";
             this.kryptonHeaderGroup1.ValuesSecondary.Image = null;
             // 
+            // ux_companys_listing
+            // 
+            this.ux_companys_listing.AllowUserToAddRows = false;
+            this.ux_companys_listing.AllowUserToDeleteRows = false;
+            this.ux_companys_listing.AllowUserToOrderColumns = true;
+            this.ux_companys_listing.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
+            this.ux_companys_listing.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.ux_companys_listing.Location = new System.Drawing.Point(0, 0);
+            this.ux_companys_listing.Name = "ux_companys_listing";
+            this.ux_companys_listing.ReadOnly = true;
+            this.ux_companys_listing.Size = new System.Drawing.Size(201, 584);
+            this.ux_companys_listing.StateCommon.BackStyle = ComponentFactory.Krypton.Toolkit.PaletteBackStyle.GridBackgroundList;
+            this.ux_companys_listing.TabIndex = 25;
+            // 
+            // kryptonSplitContainer2
+            // 
+            this.kryptonSplitContainer2.Cursor = System.Windows.Forms.Cursors.Default;
+            this.kryptonSplitContainer2.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.kryptonSplitContainer2.Location = new System.Drawing.Point(0, 0);
+            this.kryptonSplitContainer2.Name = "kryptonSplitContainer2";
+            this.kryptonSplitContainer2.Orientation = System.Windows.Forms.Orientation.Horizontal;
+            // 
+            // kryptonSplitContainer2.Panel1
+            // 
+            this.kryptonSplitContainer2.Panel1.PanelBackStyle = ComponentFactory.Krypton.Toolkit.PaletteBackStyle.FormCustom1;
+            // 
+            // kryptonSplitContainer2.Panel2
+            // 
+            this.kryptonSplitContainer2.Panel2.Controls.Add(this.ux_companys_listing);
+            this.kryptonSplitContainer2.SeparatorStyle = ComponentFactory.Krypton.Toolkit.SeparatorStyle.HighProfile;
+            this.kryptonSplitContainer2.Size = new System.Drawing.Size(201, 655);
+            this.kryptonSplitContainer2.SplitterDistance = 66;
+            this.kryptonSplitContainer2.TabIndex = 26;
+            // 
+            // kryptonGroup1
+            // 
+            this.kryptonGroup1.Location = new System.Drawing.Point(8, 3);
+            this.kryptonGroup1.Margin = new System.Windows.Forms.Padding(2);
+            this.kryptonGroup1.Name = "kryptonGroup1";
+            // 
+            // kryptonGroup1.Panel
+            // 
+            this.kryptonGroup1.Panel.Controls.Add(this.kryptonLabel1);
+            this.kryptonGroup1.Panel.Controls.Add(this.ux_cancel_button);
+            this.kryptonGroup1.Panel.Controls.Add(this.ux_company_name);
+            this.kryptonGroup1.Panel.Controls.Add(this.ux_submit_button);
+            this.kryptonGroup1.Size = new System.Drawing.Size(532, 110);
+            this.kryptonGroup1.TabIndex = 23;
+            // 
+            // kryptonGroup2
+            // 
+            this.kryptonGroup2.Location = new System.Drawing.Point(9, 141);
+            this.kryptonGroup2.Margin = new System.Windows.Forms.Padding(2);
+            this.kryptonGroup2.Name = "kryptonGroup2";
+            // 
+            // kryptonGroup2.Panel
+            // 
+            this.kryptonGroup2.Panel.Controls.Add(this.listView1);
+            this.kryptonGroup2.Size = new System.Drawing.Size(552, 273);
+            this.kryptonGroup2.TabIndex = 24;
+            // 
             // kryptonSplitContainer1
             // 
             this.kryptonSplitContainer1.Cursor = System.Windows.Forms.Cursors.Default;
             this.kryptonSplitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
             this.kryptonSplitContainer1.Location = new System.Drawing.Point(0, 0);
-            this.kryptonSplitContainer1.Margin = new System.Windows.Forms.Padding(4);
             this.kryptonSplitContainer1.Name = "kryptonSplitContainer1";
             // 
             // kryptonSplitContainer1.Panel1
             // 
             this.kryptonSplitContainer1.Panel1.Controls.Add(this.kryptonGroup2);
             this.kryptonSplitContainer1.Panel1.Controls.Add(this.kryptonGroup1);
+            this.kryptonSplitContainer1.Panel1.PanelBackStyle = ComponentFactory.Krypton.Toolkit.PaletteBackStyle.FormMain;
             // 
             // kryptonSplitContainer1.Panel2
             // 
             this.kryptonSplitContainer1.Panel2.Controls.Add(this.kryptonSplitContainer2);
             this.kryptonSplitContainer1.SeparatorStyle = ComponentFactory.Krypton.Toolkit.SeparatorStyle.HighProfile;
-            this.kryptonSplitContainer1.Size = new System.Drawing.Size(1035, 813);
-            this.kryptonSplitContainer1.SplitterDistance = 764;
+            this.kryptonSplitContainer1.Size = new System.Drawing.Size(776, 655);
+            this.kryptonSplitContainer1.SplitterDistance = 570;
             this.kryptonSplitContainer1.TabIndex = 25;
             // 
             // listView1
             // 
-            this.listView1.Dock = System.Windows.Forms.DockStyle.Fill;
-            this.listView1.Location = new System.Drawing.Point(0, 0);
+            this.listView1.Location = new System.Drawing.Point(2, 34);
+            this.listView1.Margin = new System.Windows.Forms.Padding(2);
             this.listView1.Name = "listView1";
-            this.listView1.Size = new System.Drawing.Size(734, 334);
+            this.listView1.Size = new System.Drawing.Size(550, 182);
             this.listView1.TabIndex = 21;
             this.listView1.UseCompatibleStateImageBehavior = false;
             // 
             // ux_submit_button
             // 
-            this.ux_submit_button.Location = new System.Drawing.Point(147, 77);
-            this.ux_submit_button.Margin = new System.Windows.Forms.Padding(4);
+            this.ux_submit_button.Location = new System.Drawing.Point(110, 63);
             this.ux_submit_button.Name = "ux_submit_button";
-            this.ux_submit_button.Size = new System.Drawing.Size(120, 31);
+            this.ux_submit_button.Size = new System.Drawing.Size(90, 25);
             this.ux_submit_button.TabIndex = 2;
             this.ux_submit_button.Text = "&Submit";
             this.ux_submit_button.Values.ExtraText = "";
@@ -133,119 +192,44 @@ namespace MoMoney.Presentation.Winforms.Views
             this.ux_submit_button.Values.ImageStates.ImageCheckedTracking = null;
             this.ux_submit_button.Values.Text = "&Submit";
             // 
-            // kryptonLabel1
-            // 
-            this.kryptonLabel1.Location = new System.Drawing.Point(15, 26);
-            this.kryptonLabel1.Margin = new System.Windows.Forms.Padding(4);
-            this.kryptonLabel1.Name = "kryptonLabel1";
-            this.kryptonLabel1.Size = new System.Drawing.Size(125, 24);
-            this.kryptonLabel1.TabIndex = 20;
-            this.kryptonLabel1.Text = "Company Name:";
-            this.kryptonLabel1.Values.ExtraText = "";
-            this.kryptonLabel1.Values.Image = null;
-            this.kryptonLabel1.Values.Text = "Company Name:";
-            // 
             // ux_company_name
             // 
-            this.ux_company_name.Location = new System.Drawing.Point(147, 26);
-            this.ux_company_name.Margin = new System.Windows.Forms.Padding(4);
+            this.ux_company_name.Location = new System.Drawing.Point(110, 21);
             this.ux_company_name.Name = "ux_company_name";
-            this.ux_company_name.Size = new System.Drawing.Size(547, 24);
+            this.ux_company_name.Size = new System.Drawing.Size(410, 20);
             this.ux_company_name.TabIndex = 1;
             // 
             // ux_cancel_button
             // 
             this.ux_cancel_button.DialogResult = System.Windows.Forms.DialogResult.Cancel;
             this.ux_cancel_button.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
-            this.ux_cancel_button.Location = new System.Drawing.Point(275, 77);
-            this.ux_cancel_button.Margin = new System.Windows.Forms.Padding(4);
+            this.ux_cancel_button.Location = new System.Drawing.Point(206, 63);
             this.ux_cancel_button.Name = "ux_cancel_button";
-            this.ux_cancel_button.Size = new System.Drawing.Size(76, 31);
+            this.ux_cancel_button.Size = new System.Drawing.Size(57, 25);
             this.ux_cancel_button.TabIndex = 3;
             this.ux_cancel_button.Text = "Cancel";
             this.ux_cancel_button.UseVisualStyleBackColor = true;
             // 
-            // kryptonSplitContainer2
-            // 
-            this.kryptonSplitContainer2.Cursor = System.Windows.Forms.Cursors.Default;
-            this.kryptonSplitContainer2.Dock = System.Windows.Forms.DockStyle.Fill;
-            this.kryptonSplitContainer2.Location = new System.Drawing.Point(0, 0);
-            this.kryptonSplitContainer2.Margin = new System.Windows.Forms.Padding(4);
-            this.kryptonSplitContainer2.Name = "kryptonSplitContainer2";
-            this.kryptonSplitContainer2.Orientation = System.Windows.Forms.Orientation.Horizontal;
-            // 
-            // kryptonSplitContainer2.Panel1
-            // 
-            this.kryptonSplitContainer2.Panel1.Controls.Add(this.kryptonHeader1);
-            // 
-            // kryptonSplitContainer2.Panel2
-            // 
-            this.kryptonSplitContainer2.Panel2.Controls.Add(this.ux_companys_listing);
-            this.kryptonSplitContainer2.SeparatorStyle = ComponentFactory.Krypton.Toolkit.SeparatorStyle.HighProfile;
-            this.kryptonSplitContainer2.Size = new System.Drawing.Size(266, 813);
-            this.kryptonSplitContainer2.SplitterDistance = 46;
-            this.kryptonSplitContainer2.TabIndex = 26;
-            // 
-            // kryptonHeader1
-            // 
-            this.kryptonHeader1.Location = new System.Drawing.Point(4, 4);
-            this.kryptonHeader1.Margin = new System.Windows.Forms.Padding(4);
-            this.kryptonHeader1.Name = "kryptonHeader1";
-            this.kryptonHeader1.Size = new System.Drawing.Size(144, 37);
-            this.kryptonHeader1.TabIndex = 25;
-            this.kryptonHeader1.Text = "Companys";
-            this.kryptonHeader1.Values.Description = "";
-            this.kryptonHeader1.Values.Heading = "Companys";
-            this.kryptonHeader1.Values.Image = ((System.Drawing.Image)(resources.GetObject("kryptonHeader1.Values.Image")));
-            // 
-            // ux_companys_listing
-            // 
-            this.ux_companys_listing.AllowUserToAddRows = false;
-            this.ux_companys_listing.AllowUserToDeleteRows = false;
-            this.ux_companys_listing.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
-            this.ux_companys_listing.Dock = System.Windows.Forms.DockStyle.Fill;
-            this.ux_companys_listing.Location = new System.Drawing.Point(0, 0);
-            this.ux_companys_listing.Margin = new System.Windows.Forms.Padding(4);
-            this.ux_companys_listing.Name = "ux_companys_listing";
-            this.ux_companys_listing.ReadOnly = true;
-            this.ux_companys_listing.Size = new System.Drawing.Size(266, 762);
-            this.ux_companys_listing.StateCommon.BackStyle = ComponentFactory.Krypton.Toolkit.PaletteBackStyle.GridBackgroundList;
-            this.ux_companys_listing.TabIndex = 25;
-            // 
-            // kryptonGroup1
-            // 
-            this.kryptonGroup1.Location = new System.Drawing.Point(11, 4);
-            this.kryptonGroup1.Name = "kryptonGroup1";
-            // 
-            // kryptonGroup1.Panel
-            // 
-            this.kryptonGroup1.Panel.Controls.Add(this.kryptonLabel1);
-            this.kryptonGroup1.Panel.Controls.Add(this.ux_cancel_button);
-            this.kryptonGroup1.Panel.Controls.Add(this.ux_company_name);
-            this.kryptonGroup1.Panel.Controls.Add(this.ux_submit_button);
-            this.kryptonGroup1.Size = new System.Drawing.Size(710, 135);
-            this.kryptonGroup1.TabIndex = 23;
-            // 
-            // kryptonGroup2
-            // 
-            this.kryptonGroup2.Location = new System.Drawing.Point(12, 173);
-            this.kryptonGroup2.Name = "kryptonGroup2";
-            // 
-            // kryptonGroup2.Panel
+            // kryptonLabel1
             // 
-            this.kryptonGroup2.Panel.Controls.Add(this.listView1);
-            this.kryptonGroup2.Size = new System.Drawing.Size(736, 336);
-            this.kryptonGroup2.TabIndex = 24;
+            this.kryptonLabel1.Location = new System.Drawing.Point(11, 21);
+            this.kryptonLabel1.Name = "kryptonLabel1";
+            this.kryptonLabel1.Size = new System.Drawing.Size(101, 20);
+            this.kryptonLabel1.TabIndex = 20;
+            this.kryptonLabel1.Text = "Company Name:";
+            this.kryptonLabel1.Values.ExtraText = "";
+            this.kryptonLabel1.Values.Image = null;
+            this.kryptonLabel1.Values.Text = "Company Name:";
             // 
             // AddCompanyView
             // 
             this.AcceptButton = this.ux_submit_button;
-            this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
             this.CancelButton = this.ux_cancel_button;
-            this.ClientSize = new System.Drawing.Size(1037, 876);
+            this.ClientSize = new System.Drawing.Size(778, 712);
             this.Controls.Add(this.kryptonHeaderGroup1);
-            this.Margin = new System.Windows.Forms.Padding(4);
+            this.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
             this.Name = "AddCompanyView";
             this.TabText = "AddExpenseView";
             this.Text = "Add A New Bill";
@@ -253,20 +237,12 @@ namespace MoMoney.Presentation.Winforms.Views
             this.kryptonHeaderGroup1.Panel.ResumeLayout(false);
             ((System.ComponentModel.ISupportInitialize)(this.kryptonHeaderGroup1)).EndInit();
             this.kryptonHeaderGroup1.ResumeLayout(false);
-            ((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer1.Panel1)).EndInit();
-            this.kryptonSplitContainer1.Panel1.ResumeLayout(false);
-            ((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer1.Panel2)).EndInit();
-            this.kryptonSplitContainer1.Panel2.ResumeLayout(false);
-            ((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer1)).EndInit();
-            this.kryptonSplitContainer1.ResumeLayout(false);
+            ((System.ComponentModel.ISupportInitialize)(this.ux_companys_listing)).EndInit();
             ((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer2.Panel1)).EndInit();
-            this.kryptonSplitContainer2.Panel1.ResumeLayout(false);
-            this.kryptonSplitContainer2.Panel1.PerformLayout();
             ((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer2.Panel2)).EndInit();
             this.kryptonSplitContainer2.Panel2.ResumeLayout(false);
             ((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer2)).EndInit();
             this.kryptonSplitContainer2.ResumeLayout(false);
-            ((System.ComponentModel.ISupportInitialize)(this.ux_companys_listing)).EndInit();
             ((System.ComponentModel.ISupportInitialize)(this.kryptonGroup1.Panel)).EndInit();
             this.kryptonGroup1.Panel.ResumeLayout(false);
             this.kryptonGroup1.Panel.PerformLayout();
@@ -276,6 +252,12 @@ namespace MoMoney.Presentation.Winforms.Views
             this.kryptonGroup2.Panel.ResumeLayout(false);
             ((System.ComponentModel.ISupportInitialize)(this.kryptonGroup2)).EndInit();
             this.kryptonGroup2.ResumeLayout(false);
+            ((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer1.Panel1)).EndInit();
+            this.kryptonSplitContainer1.Panel1.ResumeLayout(false);
+            ((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer1.Panel2)).EndInit();
+            this.kryptonSplitContainer1.Panel2.ResumeLayout(false);
+            ((System.ComponentModel.ISupportInitialize)(this.kryptonSplitContainer1)).EndInit();
+            this.kryptonSplitContainer1.ResumeLayout(false);
             this.ResumeLayout(false);
 
         }
@@ -283,17 +265,16 @@ namespace MoMoney.Presentation.Winforms.Views
         #endregion
 
         private ComponentFactory.Krypton.Toolkit.KryptonHeaderGroup kryptonHeaderGroup1;
-        private ComponentFactory.Krypton.Toolkit.KryptonTextBox ux_company_name;
-        private System.Windows.Forms.Button ux_cancel_button;
+        private ComponentFactory.Krypton.Toolkit.KryptonDataGridView ux_companys_listing;
         private ComponentFactory.Krypton.Toolkit.KryptonSplitContainer kryptonSplitContainer1;
+        private ComponentFactory.Krypton.Toolkit.KryptonGroup kryptonGroup2;
+        private System.Windows.Forms.ListView listView1;
+        private ComponentFactory.Krypton.Toolkit.KryptonGroup kryptonGroup1;
         private ComponentFactory.Krypton.Toolkit.KryptonLabel kryptonLabel1;
-        private ComponentFactory.Krypton.Toolkit.KryptonHeader kryptonHeader1;
+        private System.Windows.Forms.Button ux_cancel_button;
+        private ComponentFactory.Krypton.Toolkit.KryptonTextBox ux_company_name;
         private ComponentFactory.Krypton.Toolkit.KryptonButton ux_submit_button;
         private ComponentFactory.Krypton.Toolkit.KryptonSplitContainer kryptonSplitContainer2;
-        private ComponentFactory.Krypton.Toolkit.KryptonDataGridView ux_companys_listing;
-        private System.Windows.Forms.ListView listView1;
-        private ComponentFactory.Krypton.Toolkit.KryptonGroup kryptonGroup1;
-        private ComponentFactory.Krypton.Toolkit.KryptonGroup kryptonGroup2;
 
     }
 }
\ No newline at end of file
product/Presentation/Winforms/Views/AddCompanyView.resx
@@ -118,29 +118,10 @@
     <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </resheader>
   <assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
-  <data name="kryptonHeader1.Values.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
-    <value>
-        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6
-        JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAAsOAAALDgFAvuFBAAAC6UlE
-        QVQ4T43TW0jTYRgGcC+MKEQziLwQPGTqWqY25zw1/6bzsDmdeUxzMy1dmytrrU2nQWrmIZVCo4zAEgm7
-        SKSg0iLIs66ssDLdPG2armxFdpgOn6aQJCX63n7v87t4Xj4TkzUmVJK7US5y5hdJ7X+Uynfqz56yFayV
-        +ee9ppzAaKc3ND3ekJ0mFlYFxGn2lgUS+6Zrxc4oydmhPc3fTiwuN9yWo7PRHcrOSHBS0rEqkC+2rXpU
-        7wpVuw/6n9BQW7EL5bl2aKl3g7I9CKKTKfAMSRx19adu+S8ilzAnFA+Z6GtmYriTgaFWH2OQgKqLjYH2
-        WMgkHBTlErhU6I+6q9E4KXCLXwEVFoiIcG7W9ZAkIVqaEqDsYEDVG4zRF0yMPA+C9j0XU2+5RnSxDxp4
-        PF/DElBwxs6zppS0UH+ZhMJsV2Sk++BdOxOafrox7IWxPhLUgxdQUcZGdVUMxt6W4eNwJXyZiZNLQL7Y
-        Xj3U5oPB1n0Y6QqF5mUk1K8DMdpHNiJO0I5wERAcBjqbp2AlZyoOZ4lxNIMFd3pYhYn0mC23ocoFqo4g
-        DHVEYEQRBc0rBr5OlUCnToFWZYOpcRGcyC4aMsXDwo/JtTmYLmXTwxNSHXdTCBOZ0OFx1/0ADPfEQtkd
-        ZyzMD8r+ahwRRqH5AQu6CSvMareht20Lys9bzJWcM3tTWWy6d7k8+XGaXt2fB+1gnrH5EOhU6UhOJrDH
-        m4nGJgZmP23Fd5059LNmmPlgCZ02A34hjNpl4FAqP4kTF4ebdTl4dE+GG1fYcCRTIeKbl77ptcK3zxbQ
-        f98Ew/wG6KY3Y1xzB1RGYuuK86WdyBZys87eCjcWRGfFw9qGdLGwIMKj+ykVhl+ZmNeb4cuMKWCoRqYk
-        BRQ6q2xd/0EklaLhLg8fpxsw9zMHz54SoPgfWHD3DaCsC+AJxFl8WfFkkiAXrBgOiOD9ILl5PVxX+M9S
-        eHwqOZCTUBwYnawgu9MGrHeQHf4GfgNkMpj0S8vAHQAAAABJRU5ErkJggg==
-</value>
-  </data>
   <data name="kryptonHeaderGroup1.ValuesPrimary.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6
-        JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAAsOAAALDgFAvuFBAAAC6UlE
+        JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAAsMAAALDAE/QCLIAAAC6UlE
         QVQ4T43TW0jTYRgGcC+MKEQziLwQPGTqWqY25zw1/6bzsDmdeUxzMy1dmytrrU2nQWrmIZVCo4zAEgm7
         SKSg0iLIs66ssDLdPG2armxFdpgOn6aQJCX63n7v87t4Xj4TkzUmVJK7US5y5hdJ7X+Uynfqz56yFayV
         +ee9ppzAaKc3ND3ekJ0mFlYFxGn2lgUS+6Zrxc4oydmhPc3fTiwuN9yWo7PRHcrOSHBS0rEqkC+2rXpU
product/Presentation/Winforms/Views/AddNewIncomeView.cs
@@ -7,6 +7,7 @@ using MoMoney.Presentation.Views.Core;
 using MoMoney.Presentation.Views.income;
 using MoMoney.Presentation.Winforms.Helpers;
 using MoMoney.Presentation.Winforms.Krypton;
+using MoMoney.Presentation.Winforms.Resources;
 
 namespace MoMoney.Presentation.Winforms.Views
 {
@@ -18,7 +19,8 @@ namespace MoMoney.Presentation.Winforms.Views
         public AddNewIncomeView()
         {
             InitializeComponent();
-            titled("Add Income");
+            titled("Add Income")
+                .icon(ApplicationIcons.AddNewIncome);
             ux_submit_button.Click += (sender, e) => submit_button(e);
 
             companies_list = ux_companys.create_for<CompanyDTO>();
product/Presentation/Winforms/Views/CheckForUpdatesView.Designer.cs
@@ -43,40 +43,36 @@ namespace MoMoney.Presentation.Winforms.Views
             // label3
             // 
             this.label3.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
-            this.label3.Location = new System.Drawing.Point(12, 211);
-            this.label3.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
+            this.label3.Location = new System.Drawing.Point(9, 171);
             this.label3.Name = "label3";
-            this.label3.Size = new System.Drawing.Size(364, 2);
+            this.label3.Size = new System.Drawing.Size(273, 2);
             this.label3.TabIndex = 15;
             this.label3.Text = "                                                                                 " +
-                               "       ";
+                "       ";
             // 
             // label2
             // 
             this.label2.AutoSize = true;
-            this.label2.Location = new System.Drawing.Point(178, 66);
-            this.label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
+            this.label2.Location = new System.Drawing.Point(134, 54);
             this.label2.Name = "label2";
-            this.label2.Size = new System.Drawing.Size(177, 17);
+            this.label2.Size = new System.Drawing.Size(136, 13);
             this.label2.TabIndex = 14;
             this.label2.Text = "What would you like to do?";
             // 
             // ux_current_version
             // 
             this.ux_current_version.AutoSize = true;
-            this.ux_current_version.Location = new System.Drawing.Point(178, 13);
-            this.ux_current_version.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
+            this.ux_current_version.Location = new System.Drawing.Point(134, 11);
             this.ux_current_version.Name = "ux_current_version";
-            this.ux_current_version.Size = new System.Drawing.Size(59, 17);
+            this.ux_current_version.Size = new System.Drawing.Size(44, 13);
             this.ux_current_version.TabIndex = 13;
             this.ux_current_version.Text = "Current:";
             // 
             // ux_image
             // 
-            this.ux_image.Location = new System.Drawing.Point(13, 13);
-            this.ux_image.Margin = new System.Windows.Forms.Padding(4);
+            this.ux_image.Location = new System.Drawing.Point(10, 11);
             this.ux_image.Name = "ux_image";
-            this.ux_image.Size = new System.Drawing.Size(153, 105);
+            this.ux_image.Size = new System.Drawing.Size(115, 85);
             this.ux_image.TabIndex = 12;
             this.ux_image.TabStop = false;
             // 
@@ -84,10 +80,9 @@ namespace MoMoney.Presentation.Winforms.Views
             // 
             this.ux_cancel_button.DialogResult = System.Windows.Forms.DialogResult.Cancel;
             this.ux_cancel_button.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
-            this.ux_cancel_button.Location = new System.Drawing.Point(14, 311);
-            this.ux_cancel_button.Margin = new System.Windows.Forms.Padding(4);
+            this.ux_cancel_button.Location = new System.Drawing.Point(10, 253);
             this.ux_cancel_button.Name = "ux_cancel_button";
-            this.ux_cancel_button.Size = new System.Drawing.Size(356, 78);
+            this.ux_cancel_button.Size = new System.Drawing.Size(267, 63);
             this.ux_cancel_button.TabIndex = 11;
             this.ux_cancel_button.Text = "Cancel";
             this.ux_cancel_button.UseVisualStyleBackColor = true;
@@ -95,10 +90,9 @@ namespace MoMoney.Presentation.Winforms.Views
             // ux_dont_update_button
             // 
             this.ux_dont_update_button.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
-            this.ux_dont_update_button.Location = new System.Drawing.Point(14, 226);
-            this.ux_dont_update_button.Margin = new System.Windows.Forms.Padding(4);
+            this.ux_dont_update_button.Location = new System.Drawing.Point(10, 184);
             this.ux_dont_update_button.Name = "ux_dont_update_button";
-            this.ux_dont_update_button.Size = new System.Drawing.Size(356, 78);
+            this.ux_dont_update_button.Size = new System.Drawing.Size(267, 63);
             this.ux_dont_update_button.TabIndex = 10;
             this.ux_dont_update_button.Text = "Do&n\'t Update";
             this.ux_dont_update_button.UseVisualStyleBackColor = true;
@@ -106,10 +100,9 @@ namespace MoMoney.Presentation.Winforms.Views
             // ux_update_button
             // 
             this.ux_update_button.Enabled = false;
-            this.ux_update_button.Location = new System.Drawing.Point(13, 121);
-            this.ux_update_button.Margin = new System.Windows.Forms.Padding(4);
+            this.ux_update_button.Location = new System.Drawing.Point(10, 98);
             this.ux_update_button.Name = "ux_update_button";
-            this.ux_update_button.Size = new System.Drawing.Size(356, 78);
+            this.ux_update_button.Size = new System.Drawing.Size(267, 63);
             this.ux_update_button.TabIndex = 9;
             this.ux_update_button.Text = "&Update";
             this.ux_update_button.UseVisualStyleBackColor = true;
@@ -117,28 +110,27 @@ namespace MoMoney.Presentation.Winforms.Views
             // ux_new_version
             // 
             this.ux_new_version.AutoSize = true;
-            this.ux_new_version.Location = new System.Drawing.Point(182, 49);
-            this.ux_new_version.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
+            this.ux_new_version.Location = new System.Drawing.Point(136, 40);
             this.ux_new_version.Name = "ux_new_version";
-            this.ux_new_version.Size = new System.Drawing.Size(39, 17);
+            this.ux_new_version.Size = new System.Drawing.Size(32, 13);
             this.ux_new_version.TabIndex = 16;
             this.ux_new_version.Text = "New:";
             // 
             // label5
             // 
             this.label5.AutoSize = true;
-            this.label5.Location = new System.Drawing.Point(253, 32);
-            this.label5.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
+            this.label5.Location = new System.Drawing.Point(190, 26);
             this.label5.Name = "label5";
-            this.label5.Size = new System.Drawing.Size(20, 17);
+            this.label5.Size = new System.Drawing.Size(16, 13);
             this.label5.TabIndex = 17;
             this.label5.Text = "to";
             // 
             // CheckForUpdatesView
             // 
-            this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
-            this.ClientSize = new System.Drawing.Size(388, 403);
+            this.CancelButton = this.ux_cancel_button;
+            this.ClientSize = new System.Drawing.Size(291, 327);
             this.Controls.Add(this.label5);
             this.Controls.Add(this.ux_new_version);
             this.Controls.Add(this.label3);
@@ -148,7 +140,10 @@ namespace MoMoney.Presentation.Winforms.Views
             this.Controls.Add(this.ux_cancel_button);
             this.Controls.Add(this.ux_dont_update_button);
             this.Controls.Add(this.ux_update_button);
+            this.MaximizeBox = false;
+            this.MinimizeBox = false;
             this.Name = "CheckForUpdatesView";
+            this.ShowInTaskbar = false;
             this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
             this.Text = "MoMoney - Check For Updates";
             ((System.ComponentModel.ISupportInitialize)(this.ux_image)).EndInit();
product/Presentation/Winforms/Views/LogFileView.cs
@@ -1,4 +1,5 @@
 ๏ปฟusing MoMoney.Presentation.Views.Shell;
+using MoMoney.Presentation.Winforms.Resources;
 
 namespace MoMoney.Presentation.Winforms.Views
 {
@@ -11,7 +12,8 @@ namespace MoMoney.Presentation.Winforms.Views
 
         public void display(string file_path)
         {
-            titled("Log File - {0}", file_path);
+            titled("Log File - {0}", file_path)
+                .icon(ApplicationIcons.ViewLog);
         }
 
         public void run(string file_contents)
product/Presentation/Winforms/Views/StatusBarView.cs
@@ -1,4 +1,5 @@
 using System.Windows.Forms;
+using MoMoney.Presentation.Views;
 using MoMoney.Presentation.Views.Shell;
 using MoMoney.Presentation.Winforms.Resources;
 
@@ -21,5 +22,15 @@ namespace MoMoney.Presentation.Winforms.Views
                                                        x.Image = icon_to_display;
                                                    });
         }
+
+        public void reset_progress_bar()
+        {
+            shell.region<ToolStripProgressBar>(x => { x.ProgressBar.Value = 0; });
+        }
+
+        public void notify()
+        {
+            shell.region<ToolStripProgressBar>(x => { x.Increment(10); });
+        }
     }
 }
\ No newline at end of file
product/Presentation/Winforms/Views/ViewAllBills.cs
@@ -3,6 +3,7 @@ using System.Linq;
 using MoMoney.DTO;
 using MoMoney.Presentation.Presenters.billing;
 using MoMoney.Presentation.Views;
+using MoMoney.Presentation.Winforms.Resources;
 
 namespace MoMoney.Presentation.Winforms.Views
 {
@@ -11,7 +12,7 @@ namespace MoMoney.Presentation.Winforms.Views
         public ViewAllBills()
         {
             InitializeComponent();
-            titled("View Bills");
+            titled("View Bill Payments").icon(ApplicationIcons.ViewAllBillPayments);
         }
 
         public void attach_to(IViewAllBillsPresenter presenter)
product/Presentation/Winforms/Views/ViewAllIncome.cs
@@ -3,6 +3,7 @@ using Gorilla.Commons.Utility.Extensions;
 using MoMoney.DTO;
 using MoMoney.Presentation.Presenters.income;
 using MoMoney.Presentation.Views.income;
+using MoMoney.Presentation.Winforms.Resources;
 
 namespace MoMoney.Presentation.Winforms.Views
 {
@@ -11,7 +12,7 @@ namespace MoMoney.Presentation.Winforms.Views
         public ViewAllIncome()
         {
             InitializeComponent();
-            titled("View All Income");
+            titled("View All Income").icon(ApplicationIcons.ViewAllIncome);
         }
 
         public void attach_to(IViewIncomeHistoryPresenter presenter)
product/Presentation/Winforms/Views/WelcomeScreen.cs
@@ -11,7 +11,7 @@ namespace MoMoney.Presentation.Winforms.Views
         public WelcomeScreen()
         {
             InitializeComponent();
-            titled("Getting Started");
+            titled("Getting Started").icon(ApplicationIcons.Home);
 
             ux_open_existing_file_button.will_be_shown_as(ApplicationImages.OpenExistingFile)
                 .when_hovered_over_will_show(ApplicationImages.OpenExistingFileSelected)
product/Presentation/Presentation.csproj
@@ -103,6 +103,8 @@
     </Reference>
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Model\Messages\FinishedRunningCommand.cs" />
+    <Compile Include="Model\Messages\StartedRunningCommand.cs" />
     <Compile Include="Model\Navigation\INavigationTreeVisitor.cs" />
     <Compile Include="Model\Navigation\ITreeBranch.cs" />
     <Compile Include="Model\Navigation\ITreeViewToRootNodeMapper.cs" />
@@ -536,6 +538,10 @@
       <Project>{41D2B68B-031B-44FF-BAC5-7752D9E29F94}</Project>
       <Name>Service.Contracts</Name>
     </ProjectReference>
+    <ProjectReference Include="..\Service\Service.csproj">
+      <Project>{7EA4C557-6EF2-4B1F-85C8-5B3F51BAD8DB}</Project>
+      <Name>Service</Name>
+    </ProjectReference>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
product/Service/Infrastructure/Eventing/EventAggregator.cs
@@ -0,0 +1,57 @@
+using System;
+using System.Collections.Generic;
+using System.Linq.Expressions;
+using System.Threading;
+using Gorilla.Commons.Utility.Extensions;
+
+namespace MoMoney.Service.Infrastructure.Eventing
+{
+    public class EventAggregator : IEventAggregator
+    {
+        readonly SynchronizationContext context;
+        readonly HashSet<object> subscribers;
+        readonly object mutex;
+
+        public EventAggregator(SynchronizationContext context)
+        {
+            subscribers = new HashSet<object>();
+            mutex = new object();
+            this.context = context;
+        }
+
+        public void subscribe_to<Event>(IEventSubscriber<Event> subscriber) where Event : IEvent
+        {
+            subscribe(subscriber);
+        }
+
+        public void subscribe<Listener>(Listener subscriber) where Listener : class
+        {
+            within_lock(() => subscribers.Add(subscriber));
+        }
+
+        public void publish<Event>(Event the_event_to_broadcast) where Event : IEvent
+        {
+            process(() => subscribers.call_on_each<IEventSubscriber<Event>>(x => x.notify(the_event_to_broadcast)));
+        }
+
+        public void publish<T>(Expression<Action<T>> call) where T : class
+        {
+            process(() => subscribers.each(x => x.call_on(call.Compile())));
+        }
+
+        public void publish<Event>() where Event : IEvent, new()
+        {
+            publish(new Event());
+        }
+
+        void within_lock(Action action)
+        {
+            lock (mutex) action();
+        }
+
+        void process(Action action)
+        {
+            context.Send(x => action(), new object());
+        }
+    }
+}
\ No newline at end of file
product/Service/Infrastructure/Eventing/EventAggregatorSpecs.cs
@@ -0,0 +1,79 @@
+using System.Data;
+using System.Threading;
+using developwithpassion.bdd.contexts;
+using Gorilla.Commons.Testing;
+using Rhino.Mocks;
+
+namespace MoMoney.Service.Infrastructure.Eventing
+{
+    public abstract class behaves_like_event_aggregator : concerns_for<IEventAggregator, EventAggregator>
+    {
+        public override IEventAggregator create_sut()
+        {
+            return new EventAggregator(new SynchronizationContext());
+        }
+    }
+
+    [Concern(typeof(EventAggregator))]
+    public class when_a_event_is_raised_in_the_system : behaves_like_event_aggregator
+    {
+        it should_notify_all_subscribers_of_the_event = () =>
+                                                            {
+                                                                first_subscriber.was_told_to<IEventSubscriber<TestEvent>>(x => x.notify(message));
+                                                                second_subscriber.was_told_to(x => x.notify(message));
+                                                            };
+
+        it should_not_notify_any_subscribers_that_subscribed_to_a_different_event =
+            () => incorrect_subscriber.was_not_told_to(x => x.notify(Arg<AnotherEvent>.Is.Anything));
+
+        context c = () =>
+                        {
+                            message = new TestEvent();
+                            first_subscriber = an<IEventSubscriber<TestEvent>>();
+                            second_subscriber = an<IEventSubscriber<TestEvent>>();
+                            incorrect_subscriber = an<IEventSubscriber<AnotherEvent>>();
+                        };
+
+        because b = () =>
+                        {
+                            sut.subscribe_to(first_subscriber);
+                            sut.subscribe(second_subscriber);
+                            sut.publish(message);
+                        };
+
+        static TestEvent message;
+        static IEventSubscriber<TestEvent> first_subscriber;
+        static IEventSubscriber<TestEvent> second_subscriber;
+        static IEventSubscriber<AnotherEvent> incorrect_subscriber;
+    }
+
+    [Concern(typeof(EventAggregator))]
+    public class when_publishing_a_call_to_all_subscribers : behaves_like_event_aggregator
+    {
+        it should_make_the_call_on_each_subscriber = () => connection.was_told_to(x => x.ChangeDatabase("localhost"));
+
+        context c = () =>
+                        {
+                            connection = an<IDbConnection>();
+                            command = an<IDbCommand>();
+                        };
+
+        because b = () =>
+                        {
+                            sut.subscribe(connection);
+                            sut.subscribe(command);
+                            sut.publish<IDbConnection>(x => x.ChangeDatabase("localhost"));
+                        };
+
+        static IDbConnection connection;
+        static IDbCommand command;
+    }
+
+    public class TestEvent : IEvent
+    {
+    }
+
+    public class AnotherEvent : IEvent
+    {
+    }
+}
\ No newline at end of file
product/Service/Infrastructure/Eventing/IEvent.cs
@@ -0,0 +1,6 @@
+namespace MoMoney.Service.Infrastructure.Eventing
+{
+    public interface IEvent
+    {
+    }
+}
\ No newline at end of file
product/Service/Infrastructure/Eventing/IEventAggregator.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Linq.Expressions;
+
+namespace MoMoney.Service.Infrastructure.Eventing
+{
+    public interface IEventAggregator
+    {
+        void subscribe_to<Event>(IEventSubscriber<Event> subscriber) where Event : IEvent;
+        void subscribe<Listener>(Listener subscriber) where Listener : class;
+        void publish<Event>(Event the_event_to_broadcast) where Event : IEvent;
+        void publish<T>(Expression<Action<T>> call) where T : class;
+        void publish<Event>() where Event : IEvent, new();
+    }
+}
\ No newline at end of file
product/Service/Infrastructure/Eventing/IEventSubscriber.cs
@@ -0,0 +1,7 @@
+namespace MoMoney.Service.Infrastructure.Eventing
+{
+    public interface IEventSubscriber<Event> where Event : IEvent
+    {
+        void notify(Event message);
+    }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/AsynchronousCommandProcessor.cs
@@ -0,0 +1,91 @@
+using System;
+using System.Collections.Generic;
+using System.Linq.Expressions;
+using System.Threading;
+using Gorilla.Commons.Infrastructure.Threading;
+using Gorilla.Commons.Utility.Core;
+
+namespace MoMoney.Service.Infrastructure.Threading
+{
+    public class AsynchronousCommandProcessor : ICommandProcessor
+    {
+        readonly Queue<ICommand> queued_commands;
+        readonly EventWaitHandle manual_reset;
+        readonly IList<Thread> worker_threads;
+        bool keep_working;
+
+        public AsynchronousCommandProcessor()
+        {
+            queued_commands = new Queue<ICommand>();
+            worker_threads = new List<Thread>();
+            manual_reset = new ManualResetEvent(false);
+        }
+
+        public void add(Expression<Action> action_to_process)
+        {
+            add(new ActionCommand(action_to_process));
+        }
+
+        public void add(ICommand command_to_process)
+        {
+            lock (queued_commands)
+            {
+                if (queued_commands.Contains(command_to_process)) return;
+                queued_commands.Enqueue(command_to_process);
+                reset_thread();
+            }
+        }
+
+        public void run()
+        {
+            reset_thread();
+            keep_working = true;
+            var worker_thread = new Thread(run_commands);
+            worker_thread.SetApartmentState(ApartmentState.STA);
+            worker_threads.Add(worker_thread);
+            worker_thread.Start();
+        }
+
+        public void stop()
+        {
+            keep_working = false;
+            manual_reset.Set();
+            //manual_reset.Close();
+        }
+
+        [STAThread]
+        void run_commands()
+        {
+            while (keep_working)
+            {
+                manual_reset.WaitOne();
+                run_next_command();
+            }
+        }
+
+        void run_next_command()
+        {
+            ICommand command;
+            lock (queued_commands)
+            {
+                if (queued_commands.Count == 0)
+                {
+                    manual_reset.Reset();
+                    return;
+                }
+                command = queued_commands.Dequeue();
+            }
+            command.run();
+            reset_thread();
+        }
+
+        void reset_thread()
+        {
+            lock (queued_commands)
+            {
+                if (queued_commands.Count > 0) manual_reset.Set();
+                else manual_reset.Reset();
+            }
+        }
+    }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/BackgroundThread.cs
@@ -0,0 +1,34 @@
+using MoMoney.Utility.Core;
+
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+    public interface IBackgroundThread : IDisposableCommand
+    {
+    }
+
+    public class BackgroundThread : IBackgroundThread
+    {
+        readonly IWorkerThread worker_thread;
+
+        public BackgroundThread(IDisposableCommand command_to_execute) : this(command_to_execute, new WorkerThread())
+        {
+        }
+
+        public BackgroundThread(IDisposableCommand command_to_execute, IWorkerThread worker_thread)
+        {
+            this.worker_thread = worker_thread;
+            worker_thread.DoWork += (sender, e) => command_to_execute.run();
+            worker_thread.Disposed += (sender, e) => command_to_execute.Dispose();
+        }
+
+        public void run()
+        {
+            worker_thread.begin();
+        }
+
+        public void Dispose()
+        {
+            worker_thread.Dispose();
+        }
+    }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/BackgroundThreadFactory.cs
@@ -0,0 +1,33 @@
+using System;
+using Gorilla.Commons.Infrastructure.Container;
+using Gorilla.Commons.Utility.Core;
+using MoMoney.Utility.Core;
+
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+    public interface IBackgroundThreadFactory
+    {
+        IBackgroundThread create_for<CommandToExecute>() where CommandToExecute : IDisposableCommand;
+        IBackgroundThread create_for(Action action);
+    }
+
+    public class BackgroundThreadFactory : IBackgroundThreadFactory
+    {
+        private readonly IDependencyRegistry registry;
+
+        public BackgroundThreadFactory(IDependencyRegistry registry)
+        {
+            this.registry = registry;
+        }
+
+        public IBackgroundThread create_for<CommandToExecute>() where CommandToExecute : IDisposableCommand
+        {
+            return new BackgroundThread(registry.get_a<CommandToExecute>());
+        }
+
+        public IBackgroundThread create_for(Action action)
+        {
+            return new BackgroundThread(new DisposableCommand(action));
+        }
+    }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/BackgroundThreadFactorySpecs.cs
@@ -0,0 +1,28 @@
+using developwithpassion.bdd.contexts;
+using Gorilla.Commons.Infrastructure.Container;
+using Gorilla.Commons.Testing;
+using MoMoney.Utility.Core;
+
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+    [Concern(typeof (BackgroundThreadFactory))]
+    public abstract class behaves_like_a_background_thread_factory : concerns_for<IBackgroundThreadFactory, BackgroundThreadFactory>
+    {
+        context c = () => { registry = the_dependency<IDependencyRegistry>(); };
+
+        protected static IDependencyRegistry registry;
+    }
+
+    [Concern(typeof (BackgroundThreadFactory))]
+    public class when_creating_a_background_thread : behaves_like_a_background_thread_factory
+    {
+        it should_return_an_instance_of_a_background_thread = () => result.should_not_be_null();
+
+        it should_lookup_an_instance_of_the_command_to_execute =
+            () => registry.was_told_to(r => r.get_a<IDisposableCommand>());
+
+        because b = () => { result = sut.create_for<IDisposableCommand>(); };
+
+        static IBackgroundThread result;
+    }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/BackgroundThreadSpecs.cs
@@ -0,0 +1,42 @@
+using developwithpassion.bdd.contexts;
+using Gorilla.Commons.Testing;
+using MoMoney.Utility.Core;
+using Rhino.Mocks;
+
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+    [Concern(typeof (BackgroundThread))]
+    public abstract class behaves_like_a_background_thread : concerns_for<IBackgroundThread, BackgroundThread>
+    {
+        context c = () =>
+                        {
+                            command_to_execute = the_dependency<IDisposableCommand>();
+                            worker_thread = the_dependency<IWorkerThread>();
+                        };
+
+        protected static IDisposableCommand command_to_execute;
+        protected static IWorkerThread worker_thread;
+    }
+
+    [Concern(typeof (BackgroundThread))]
+    public class when_executing_a_command_on_a_background_thread : behaves_like_a_background_thread
+    {
+        it should_execute_the_command_asynchronously = () => command_to_execute.was_told_to(c => c.run());
+
+        it should_start_the_worker_thread_asynchronously = () => worker_thread.was_told_to(t => t.begin());
+
+        because b = () =>
+                        {
+                            sut.run();
+                            worker_thread.Raise(t => t.DoWork += null, null, null);
+                        };
+    }
+
+    [Concern(typeof (BackgroundThread))]
+    public class when_disposing_a_background_thread : behaves_like_a_background_thread
+    {
+        it should_dispose_the_command_running_on_the_thread = () => worker_thread.was_told_to(w => w.Dispose());
+
+        because b = () => sut.Dispose();
+    }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/CommandProcessor.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+using System.Linq.Expressions;
+using Gorilla.Commons.Utility.Core;
+
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+    public class CommandProcessor : ICommandProcessor
+    {
+        readonly Queue<ICommand> queued_commands;
+
+        public CommandProcessor()
+        {
+            queued_commands = new Queue<ICommand>();
+        }
+
+        public void add(Expression<Action> action_to_process)
+        {
+            add(new ActionCommand(action_to_process));
+        }
+
+        public void add(ICommand command_to_process)
+        {
+            queued_commands.Enqueue(command_to_process);
+        }
+
+        public void run()
+        {
+            while (queued_commands.Count > 0) queued_commands.Dequeue().run();
+        }
+
+        public void stop()
+        {
+            queued_commands.Clear();
+        }
+    }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/CommandProcessorSpecs.cs
@@ -0,0 +1,53 @@
+using developwithpassion.bdd.contexts;
+using Gorilla.Commons.Testing;
+using Gorilla.Commons.Utility.Core;
+
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+    [Concern(typeof (CommandProcessor))]
+    public abstract class behaves_like_a_command_processor : concerns_for<ICommandProcessor, CommandProcessor>
+    {
+    }
+
+    [Concern(typeof (CommandProcessor))]
+    public class when_running_all_the_queued_commands_waiting_for_execution : behaves_like_a_command_processor
+    {
+        it should_run_the_first_command_in_the_queue = () => first_command.was_told_to(f => f.run());
+
+        it should_run_the_second_command_in_the_queue = () => second_command.was_told_to(f => f.run());
+
+        context c = () =>
+                        {
+                            first_command = an<ICommand>();
+                            second_command = an<ICommand>();
+                        };
+
+        because b = () =>
+                        {
+                            sut.add(first_command);
+                            sut.add(second_command);
+                            sut.run();
+                        };
+
+        static ICommand first_command;
+        static ICommand second_command;
+    }
+
+    [Concern(typeof (CommandProcessor))]
+    public class when_attempting_to_rerun_the_command_processor : behaves_like_a_command_processor
+    {
+        it should_not_re_run_the_commands_that_have_already_executed =
+            () => first_command.was_told_to(f => f.run()).only_once();
+
+        context c = () => { first_command = an<ICommand>(); };
+
+        because b = () =>
+                        {
+                            sut.add(first_command);
+                            sut.run();
+                            sut.run();
+                        };
+
+        static ICommand first_command;
+    }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/ICommandProcessor.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Linq.Expressions;
+using Gorilla.Commons.Utility.Core;
+
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+    public interface ICommandProcessor : ICommand
+    {
+        void add(Expression<Action> action_to_process);
+        void add(ICommand command_to_process);
+        void stop();
+    }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/IntervalTimer.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+using System.Timers;
+using Gorilla.Commons.Infrastructure.Threading;
+
+namespace MoMoney.Service.Infrastructure.Threading
+{
+    public interface ITimer
+    {
+        void start_notifying(ITimerClient client_to_be_notified, TimeSpan span);
+        void stop_notifying(ITimerClient client_to_stop_notifying);
+    }
+
+    public class IntervalTimer : ITimer
+    {
+        readonly ITimerFactory factory;
+        readonly IDictionary<ITimerClient, Timer> timers;
+
+        public IntervalTimer() : this(new TimerFactory())
+        {
+        }
+
+        public IntervalTimer(ITimerFactory factory)
+        {
+            this.factory = factory;
+            timers = new Dictionary<ITimerClient, Timer>();
+        }
+
+        public void start_notifying(ITimerClient client_to_be_notified, TimeSpan span)
+        {
+            stop_notifying(client_to_be_notified);
+
+            var timer = factory.create_for(span);
+            timer.Elapsed += (sender, args) => client_to_be_notified.notify();
+            timer.Start();
+            timers[client_to_be_notified] = timer;
+        }
+
+        public void stop_notifying(ITimerClient client_to_stop_notifying)
+        {
+            if (!timers.ContainsKey(client_to_stop_notifying)) return;
+            timers[client_to_stop_notifying].Stop();
+            timers[client_to_stop_notifying].Dispose();
+        }
+    }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/IntervalTimerSpecs.cs
@@ -0,0 +1,131 @@
+using System;
+using System.Timers;
+using developwithpassion.bdd.contexts;
+using Gorilla.Commons.Testing;
+using MoMoney.Service.Infrastructure.Threading;
+using Rhino.Mocks;
+
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+    [Concern(typeof (IntervalTimer))]
+    public abstract class behaves_like_an_interval_timer : concerns_for<ITimer, IntervalTimer>
+    {
+        context c = () => { factory = the_dependency<ITimerFactory>(); };
+
+        protected static ITimerFactory factory;
+    }
+
+    [Concern(typeof (IntervalTimer))]
+    public class when_starting_a_timer_for_a_new_client : behaves_like_an_interval_timer
+    {
+        static ITimerClient client;
+        static Timer timer;
+
+        it should_create_a_new_timer = () => factory.was_told_to(f => f.create_for(new TimeSpan(0, 10, 0)));
+
+        it should_start_the_timer = () => timer.was_told_to(t => t.Start());
+
+        context c = () =>
+                        {
+                            client = an<ITimerClient>();
+                            timer = dependency<Timer>();
+
+                            factory.is_told_to(f => f.create_for(new TimeSpan(0, 10, 0))).it_will_return(timer);
+                        };
+
+        because b = () => sut.start_notifying(client, new TimeSpan(0, 10, 0));
+    }
+
+    [Concern(typeof (IntervalTimer))]
+    public class when_starting_a_timer_for_an_existing_client : behaves_like_an_interval_timer
+    {
+        it should_stop_the_previously_started_timer = () =>
+                                                          {
+                                                              first_timer.was_told_to(t => t.Stop());
+                                                              first_timer.was_told_to(t => t.Dispose());
+                                                          };
+
+        it should_start_a_new_timer = () => second_timer.was_told_to(t => t.Start());
+
+        context c = () =>
+                        {
+                            client = an<ITimerClient>();
+                            first_timer = dependency<Timer>();
+                            second_timer = dependency<Timer>();
+
+                            factory.is_told_to(f => f.create_for(new TimeSpan(0, 1, 1))).it_will_return(first_timer);
+                            factory.is_told_to(f => f.create_for(new TimeSpan(0, 2, 2))).it_will_return(second_timer);
+                        };
+
+        because b = () =>
+                        {
+                            sut.start_notifying(client, new TimeSpan(0, 1, 1));
+                            sut.start_notifying(client, new TimeSpan(0, 2, 2));
+                        };
+
+        static ITimerClient client;
+        static Timer first_timer;
+        static Timer second_timer;
+    }
+
+    [Concern(typeof (IntervalTimer))]
+    public class when_a_timer_elapses : behaves_like_an_interval_timer
+    {
+        it should_notify_the_timer_client = () => client.was_told_to(c => c.notify());
+
+        static ITimerClient client;
+        static Timer timer;
+
+        context c = () =>
+                        {
+                            client = an<ITimerClient>();
+                            timer = dependency<Timer>();
+                            factory.is_told_to(f => f.create_for(Arg<TimeSpan>.Is.Anything)).it_will_return(timer);
+                        };
+
+        because b = () =>
+                        {
+                            sut.start_notifying(client, new TimeSpan(0, 10, 0));
+                            timer.Raise(t => t.Elapsed += null, timer, null);
+                        };
+    }
+
+    [Concern(typeof (IntervalTimer))]
+    public class when_stopping_notifications_for_an_existing_timer_client : behaves_like_an_interval_timer
+    {
+        static ITimerClient client;
+        static Timer timer;
+
+        it should_stop_the_timer_that_was_started_for_the_client = () => timer.was_told_to(t => t.Stop());
+
+        it should_dispose_the_timer_that_was_started_for_the_client = () => timer.was_told_to(t => t.Dispose());
+
+        context c = () =>
+                        {
+                            client = an<ITimerClient>();
+                            timer = dependency<Timer>();
+
+                            when_the(factory).is_told_to(t => t.create_for(Arg<TimeSpan>.Is.Anything)).it_will_return(
+                                timer);
+                        };
+
+        because b = () =>
+                        {
+                            sut.start_notifying(client, new TimeSpan(0, 0, 1));
+                            sut.stop_notifying(client);
+                        };
+    }
+
+    [Concern(typeof (IntervalTimer))]
+    public class when_attempting_to_stop_notification_for_a_client_that_doesnt_have_a_timer_started_for_it :
+        behaves_like_an_interval_timer
+    {
+        it should_not_blow_up = () => { };
+
+        context c = () => { client = an<ITimerClient>(); };
+
+        because b = () => sut.stop_notifying(client);
+
+        static ITimerClient client;
+    }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/ITimerClient.cs
@@ -0,0 +1,7 @@
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+    public interface ITimerClient
+    {
+        void notify();
+    }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/IWorkerThread.cs
@@ -0,0 +1,12 @@
+using System;
+using System.ComponentModel;
+
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+    public interface IWorkerThread : IDisposable
+    {
+        event DoWorkEventHandler DoWork;
+        event EventHandler Disposed;
+        void begin();
+    }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/RaiseEventInterceptor.cs
@@ -0,0 +1,25 @@
+using Castle.Core.Interceptor;
+using MoMoney.Service.Infrastructure.Eventing;
+
+namespace Gorilla.Commons.Infrastructure.Castle.DynamicProxy.Interceptors
+{
+    public interface IRaiseEventInterceptor<Event> : IInterceptor where Event : IEvent, new()
+    {
+    }
+
+    public class RaiseEventInterceptor<Event> : IRaiseEventInterceptor<Event> where Event : IEvent, new()
+    {
+        readonly IEventAggregator broker;
+
+        public RaiseEventInterceptor(IEventAggregator broker)
+        {
+            this.broker = broker;
+        }
+
+        public void Intercept(IInvocation invocation)
+        {
+            invocation.Proceed();
+            broker.publish(new Event());
+        }
+    }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/RunOnBackgroundThreadInterceptor.cs
@@ -0,0 +1,25 @@
+using Castle.Core.Interceptor;
+using Gorilla.Commons.Infrastructure.Threading;
+using MoMoney.Utility.Core;
+
+namespace Gorilla.Commons.Infrastructure.Castle.DynamicProxy.Interceptors
+{
+    public class RunOnBackgroundThreadInterceptor<CommandToExecute> : IInterceptor
+        where CommandToExecute : IDisposableCommand
+    {
+        readonly IBackgroundThreadFactory thread_factory;
+
+        public RunOnBackgroundThreadInterceptor(IBackgroundThreadFactory thread_factory)
+        {
+            this.thread_factory = thread_factory;
+        }
+
+        public virtual void Intercept(IInvocation invocation)
+        {
+            using (thread_factory.create_for<CommandToExecute>())
+            {
+                invocation.Proceed();
+            }
+        }
+    }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/RunOnBackgroundThreadInterceptorSpecs.cs
@@ -0,0 +1,45 @@
+using Castle.Core.Interceptor;
+using developwithpassion.bdd.contexts;
+using Gorilla.Commons.Infrastructure.Threading;
+using Gorilla.Commons.Testing;
+using MoMoney.Utility.Core;
+
+namespace Gorilla.Commons.Infrastructure.Castle.DynamicProxy.Interceptors
+{
+    [Concern(typeof (RunOnBackgroundThreadInterceptor<>))]
+    public abstract class behaves_like_background_thread_interceptor :
+        concerns_for<IInterceptor, RunOnBackgroundThreadInterceptor<IDisposableCommand>>
+    {
+        context c = () => { thread_factory = the_dependency<IBackgroundThreadFactory>(); };
+
+        static protected IBackgroundThreadFactory thread_factory;
+    }
+
+    [Concern(typeof (RunOnBackgroundThreadInterceptor<>))]
+    public class when_intercepting_a_call_to_a_method_that_takes_a_long_time_to_complete :
+        behaves_like_background_thread_interceptor
+    {
+        context c = () =>
+                        {
+                            invocation = an<IInvocation>();
+                            background_thread = an<IBackgroundThread>();
+                            thread_factory
+                                .is_told_to(f => f.create_for<IDisposableCommand>())
+                                .it_will_return(background_thread);
+                        };
+
+        because b = () => sut.Intercept(invocation);
+
+        it should_display_a_progress_bar_on_a_background_thread =
+            () => thread_factory.was_told_to(f => f.create_for<IDisposableCommand>());
+
+        it should_proceed_with_the_orginal_invocation_on_the_actual_object =
+            () => invocation.was_told_to(i => i.Proceed());
+
+        it should_hide_the_progress_bar_when_the_invocation_is_completed =
+            () => background_thread.was_told_to(b => b.Dispose());
+
+        static IInvocation invocation;
+        static IBackgroundThread background_thread;
+    }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/RunOnUIThread.cs
@@ -0,0 +1,25 @@
+using Castle.Core.Interceptor;
+using Gorilla.Commons.Infrastructure.Threading;
+using Gorilla.Commons.Utility.Core;
+
+namespace Gorilla.Commons.Infrastructure.Castle.DynamicProxy.Interceptors
+{
+    public class RunOnUIThread : IInterceptor
+    {
+        readonly ISynchronizationContextFactory factory;
+
+        public RunOnUIThread() : this(Lazy.load<ISynchronizationContextFactory>())
+        {
+        }
+
+        public RunOnUIThread(ISynchronizationContextFactory factory)
+        {
+            this.factory = factory;
+        }
+
+        public void Intercept(IInvocation invocation)
+        {
+            factory.create().run(new ActionCommand(invocation.Proceed));
+        }
+    }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/SynchronizationContextFactory.cs
@@ -0,0 +1,25 @@
+using System.Threading;
+using Gorilla.Commons.Infrastructure.Container;
+using Gorilla.Commons.Utility.Core;
+
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+    public interface ISynchronizationContextFactory : IFactory<ISynchronizationContext>
+    {
+    }
+
+    public class SynchronizationContextFactory : ISynchronizationContextFactory
+    {
+        readonly IDependencyRegistry registry;
+
+        public SynchronizationContextFactory(IDependencyRegistry registry)
+        {
+            this.registry = registry;
+        }
+
+        public ISynchronizationContext create()
+        {
+            return new SynchronizedContext(registry.get_a<SynchronizationContext>());
+        }
+    }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/SynchronizedCommand.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Threading;
+using Gorilla.Commons.Utility.Core;
+
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+    public interface ISynchronizedCommand : IParameterizedCommand<Action>, IParameterizedCommand<ICommand>
+    {
+    }
+
+    public class SynchronizedCommand : ISynchronizedCommand
+    {
+        readonly SynchronizationContext context;
+
+        public SynchronizedCommand(SynchronizationContext context)
+        {
+            this.context = context;
+        }
+
+        public void run(Action item)
+        {
+            context.Post(x => item(), new object());
+        }
+
+        public void run(ICommand item)
+        {
+            run(item.run);
+        }
+    }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/SynchronizedContext.cs
@@ -0,0 +1,25 @@
+using System.Threading;
+using Gorilla.Commons.Utility.Core;
+
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+    public interface ISynchronizationContext : IParameterizedCommand<ICommand>
+    {
+    }
+
+    public class SynchronizedContext : ISynchronizationContext
+    {
+        readonly SynchronizationContext context;
+
+        public SynchronizedContext(SynchronizationContext context)
+        {
+            this.context = context;
+        }
+
+        public void run(ICommand item)
+        {
+            context.Post(x => item.run(), new object());
+            //context.Send(x => item.run(), new object());
+        }
+    }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/Synchronizer.cs
@@ -0,0 +1,189 @@
+using System;
+using System.Collections;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Security.Permissions;
+using System.Threading;
+
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+    [SecurityPermission(SecurityAction.Demand, ControlThread = true)]
+    public class Synchronizer : ISynchronizeInvoke, IDisposable
+    {
+        readonly WorkerThread worker_thread;
+
+        public Synchronizer()
+        {
+            worker_thread = new WorkerThread(this);
+        }
+
+        public bool InvokeRequired
+        {
+            get { return ReferenceEquals(Thread.CurrentThread, worker_thread); }
+        }
+
+        public IAsyncResult BeginInvoke(Delegate method, object[] args)
+        {
+            var result = new WorkItem(null, method, args);
+            worker_thread.queue_work_item(result);
+            return result;
+        }
+
+        public object EndInvoke(IAsyncResult result)
+        {
+            result.AsyncWaitHandle.WaitOne();
+            return ((WorkItem) result).MethodReturnedValue;
+        }
+
+        public object Invoke(Delegate method, object[] args)
+        {
+            return EndInvoke(BeginInvoke(method, args));
+        }
+
+        ~Synchronizer()
+        {
+        }
+
+        public void Dispose()
+        {
+            worker_thread.kill();
+        }
+
+        class WorkerThread
+        {
+            Thread thread;
+            bool end_loop;
+            readonly Mutex end_loop_mutex;
+            readonly AutoResetEvent item_added;
+            Synchronizer synchronizer;
+            readonly Queue work_item_queue;
+
+            internal WorkerThread(Synchronizer synchronizer)
+            {
+                this.synchronizer = synchronizer;
+                end_loop = false;
+                thread = null;
+                end_loop_mutex = new Mutex();
+                item_added = new AutoResetEvent(false);
+                work_item_queue = new Queue();
+                create_thread(true);
+            }
+
+            internal void queue_work_item(WorkItem work_item)
+            {
+                lock (work_item_queue.SyncRoot)
+                {
+                    work_item_queue.Enqueue(work_item);
+                    item_added.Set();
+                }
+            }
+
+            bool EndLoop
+            {
+                set
+                {
+                    end_loop_mutex.WaitOne();
+                    end_loop = value;
+                    end_loop_mutex.ReleaseMutex();
+                }
+                get
+                {
+                    var result = false;
+                    end_loop_mutex.WaitOne();
+                    result = end_loop;
+                    end_loop_mutex.ReleaseMutex();
+                    return result;
+                }
+            }
+
+            Thread create_thread(bool auto_start)
+            {
+                if (thread != null)
+                {
+                    Debug.Assert(false);
+                    return thread;
+                }
+                thread = new Thread(run) {Name = "Synchronizer Worker Thread"};
+                if (auto_start)
+                {
+                    thread.Start();
+                }
+                return thread;
+            }
+
+            void start()
+            {
+                Debug.Assert(thread != null);
+                Debug.Assert(thread.IsAlive == false);
+                thread.Start();
+            }
+
+            bool queue_empty
+            {
+                get
+                {
+                    lock (work_item_queue.SyncRoot)
+                    {
+                        if (work_item_queue.Count > 0)
+                        {
+                            return false;
+                        }
+                        return true;
+                    }
+                }
+            }
+
+            WorkItem GetNext()
+            {
+                if (queue_empty)
+                {
+                    return null;
+                }
+                lock (work_item_queue.SyncRoot)
+                {
+                    return (WorkItem) work_item_queue.Dequeue();
+                }
+            }
+
+            void run()
+            {
+                while (EndLoop == false)
+                {
+                    while (queue_empty == false)
+                    {
+                        if (EndLoop)
+                        {
+                            return;
+                        }
+                        var workItem = GetNext();
+                        workItem.CallBack();
+                    }
+                    item_added.WaitOne();
+                }
+            }
+
+            public void kill()
+            {
+                //Kill is called on client thread - must use cached thread object
+                Debug.Assert(thread != null);
+                if (thread.IsAlive == false)
+                {
+                    return;
+                }
+                EndLoop = true;
+                item_added.Set();
+
+                //Wait for thread to die
+                thread.Join();
+                if (end_loop_mutex != null)
+                {
+                    end_loop_mutex.Close();
+                }
+                if (item_added != null)
+                {
+                    item_added.Close();
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/ThreadingExtensions.cs
@@ -0,0 +1,12 @@
+using MoMoney.Utility.Core;
+
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+    public static class ThreadingExtensions
+    {
+        public static IBackgroundThread on_a_background_thread(this IDisposableCommand command)
+        {
+            return new BackgroundThread(command);
+        }
+    }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/TimerFactory.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Timers;
+
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+    public interface ITimerFactory
+    {
+        Timer create_for(TimeSpan span);
+    }
+
+    public class TimerFactory : ITimerFactory
+    {
+        public Timer create_for(TimeSpan span)
+        {
+            if (span.Seconds > 0) {
+                var milliseconds = span.Seconds*1000;
+                return new Timer(milliseconds);
+            }
+            return new Timer(span.Ticks);
+        }
+    }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/TimerFactorySpecs.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Timers;
+using developwithpassion.bdd.contexts;
+using Gorilla.Commons.Testing;
+
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+    [Concern(typeof (TimerFactory))]
+    public abstract class behaves_like_a_timer_factory : concerns_for<ITimerFactory, TimerFactory>
+    {
+        public override ITimerFactory create_sut()
+        {
+            return new TimerFactory();
+        }
+    }
+
+    [Concern(typeof (TimerFactory))]
+    public class when_creating_a_timer : behaves_like_a_timer_factory
+    {
+        it should_return_a_timer_with_the_correct_interval = () => result.Interval.should_be_equal_to(1000);
+
+        because b = () => { result = sut.create_for(new TimeSpan(0, 0, 1)); };
+
+        static Timer result;
+    }
+
+    [Concern(typeof (TimerFactory))]
+    public class when_creating_a_timer_with_an_interval_in_milliseconds : behaves_like_a_timer_factory
+    {
+        it should_return_a_timer_with_the_correct_polling_interval =
+            () => result.Interval.should_be_equal_to(milliseconds);
+
+        because b = () =>
+                        {
+                            var timer_interval = new TimeSpan(50);
+                            milliseconds = 50;
+                            result = sut.create_for(timer_interval);
+                        };
+
+        static Timer result;
+        static double milliseconds;
+    }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/WorkerThread.cs
@@ -0,0 +1,50 @@
+using System;
+using System.ComponentModel;
+using Gorilla.Commons.Infrastructure.Logging;
+
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+    public class WorkerThread : Component, IWorkerThread
+    {
+        static readonly object do_work_key = new object();
+        bool is_running;
+        readonly Action background_thread;
+
+        public WorkerThread()
+        {
+            background_thread = worker_thread_start;
+        }
+
+        public event DoWorkEventHandler DoWork
+        {
+            add { Events.AddHandler(do_work_key, value); }
+            remove { Events.RemoveHandler(do_work_key, value); }
+        }
+
+        public void begin()
+        {
+            if (is_running)
+            {
+                throw new InvalidOperationException("Worker Thread Is Already Running");
+            }
+            is_running = true;
+            background_thread.BeginInvoke(null, null);
+        }
+
+        void worker_thread_start()
+        {
+            try
+            {
+                var handler = (DoWorkEventHandler) Events[do_work_key];
+                if (handler != null)
+                {
+                    handler(this, new DoWorkEventArgs(null));
+                }
+            }
+            catch (Exception e)
+            {
+                this.log().error(e);
+            }
+        }
+    }
+}
\ No newline at end of file
product/Service/Infrastructure/Threading/WorkItem.cs
@@ -0,0 +1,93 @@
+using System;
+using System.Threading;
+
+namespace Gorilla.Commons.Infrastructure.Threading
+{
+    [Serializable]
+    internal class WorkItem : IAsyncResult
+    {
+        readonly object[] args;
+        readonly object async_state;
+        bool completed;
+        readonly Delegate method;
+        readonly ManualResetEvent reset_event;
+        object returned_value;
+
+        internal WorkItem(object async_state, Delegate method, object[] args)
+        {
+            this.async_state = async_state;
+            this.method = method;
+            this.args = args;
+            reset_event = new ManualResetEvent(false);
+            completed = false;
+        }
+
+        //IAsyncResult properties 
+        object IAsyncResult.AsyncState
+        {
+            get { return async_state; }
+        }
+
+        WaitHandle IAsyncResult.AsyncWaitHandle
+        {
+            get { return reset_event; }
+        }
+
+        bool IAsyncResult.CompletedSynchronously
+        {
+            get { return false; }
+        }
+
+        bool IAsyncResult.IsCompleted
+        {
+            get { return Completed; }
+        }
+
+        bool Completed
+        {
+            get
+            {
+                lock (this)
+                {
+                    return completed;
+                }
+            }
+            set
+            {
+                lock (this)
+                {
+                    completed = value;
+                }
+            }
+        }
+
+        //This method is called on the worker thread to execute the method
+        internal void CallBack()
+        {
+            MethodReturnedValue = method.DynamicInvoke(args);
+            //Method is done. Signal the world
+            reset_event.Set();
+            Completed = true;
+        }
+
+        internal object MethodReturnedValue
+        {
+            get
+            {
+                object method_returned_value;
+                lock (this)
+                {
+                    method_returned_value = returned_value;
+                }
+                return method_returned_value;
+            }
+            set
+            {
+                lock (this)
+                {
+                    returned_value = value;
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
product/Service/Service.csproj
@@ -35,6 +35,14 @@
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\build\lib\test\bdd.doc\bdddoc.dll</HintPath>
     </Reference>
+    <Reference Include="Castle.Core, Version=1.0.3.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\build\lib\app\castle\Castle.Core.dll</HintPath>
+    </Reference>
+    <Reference Include="Castle.DynamicProxy2, Version=2.0.3.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\build\lib\app\castle\Castle.DynamicProxy2.dll</HintPath>
+    </Reference>
     <Reference Include="developwithpassion.bdd, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\build\lib\test\developwithpassion\developwithpassion.bdd.dll</HintPath>
@@ -43,6 +51,10 @@
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\build\lib\app\gorilla\gorilla.commons.infrastructure.dll</HintPath>
     </Reference>
+    <Reference Include="gorilla.commons.infrastructure.thirdparty, Version=2009.9.5.2051, Culture=neutral, PublicKeyToken=687787ccb6c36c9f, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\build\lib\app\gorilla\gorilla.commons.infrastructure.thirdparty.dll</HintPath>
+    </Reference>
     <Reference Include="gorilla.commons.utility, Version=2009.5.5.1633, Culture=neutral, PublicKeyToken=687787ccb6c36c9f, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\build\lib\app\gorilla\gorilla.commons.utility.dll</HintPath>
@@ -86,11 +98,43 @@
     <Compile Include="Application\IEventLog.cs" />
     <Compile Include="Application\RegisterNewCompanyCommand.cs" />
     <Compile Include="Application\SaveNewBillCommand.cs" />
+    <Compile Include="Infrastructure\Eventing\EventAggregator.cs" />
+    <Compile Include="Infrastructure\Eventing\EventAggregatorSpecs.cs" />
+    <Compile Include="Infrastructure\Eventing\IEvent.cs" />
+    <Compile Include="Infrastructure\Eventing\IEventAggregator.cs" />
+    <Compile Include="Infrastructure\Eventing\IEventSubscriber.cs" />
     <Compile Include="Infrastructure\Logging\LogFileTasks.cs" />
     <Compile Include="Infrastructure\ProjectTasks.cs" />
     <Compile Include="Infrastructure\Security\IsInRole.cs" />
     <Compile Include="Infrastructure\Security\IsInRoleSpecs.cs" />
     <Compile Include="Infrastructure\Security\Role.cs" />
+    <Compile Include="Infrastructure\Threading\AsynchronousCommandProcessor.cs" />
+    <Compile Include="Infrastructure\Threading\BackgroundThread.cs" />
+    <Compile Include="Infrastructure\Threading\BackgroundThreadFactory.cs" />
+    <Compile Include="Infrastructure\Threading\BackgroundThreadFactorySpecs.cs" />
+    <Compile Include="Infrastructure\Threading\BackgroundThreadSpecs.cs" />
+    <Compile Include="Infrastructure\Threading\CommandProcessor.cs" />
+    <Compile Include="Infrastructure\Threading\CommandProcessorSpecs.cs" />
+    <Compile Include="Infrastructure\Threading\ICommandProcessor.cs" />
+    <Compile Include="Infrastructure\Threading\IntervalTimer.cs" />
+    <Compile Include="Infrastructure\Threading\IntervalTimerSpecs.cs" />
+    <Compile Include="Infrastructure\Threading\ITimerClient.cs" />
+    <Compile Include="Infrastructure\Threading\IWorkerThread.cs" />
+    <Compile Include="Infrastructure\Threading\RaiseEventInterceptor.cs" />
+    <Compile Include="Infrastructure\Threading\RunOnBackgroundThreadInterceptor.cs" />
+    <Compile Include="Infrastructure\Threading\RunOnBackgroundThreadInterceptorSpecs.cs" />
+    <Compile Include="Infrastructure\Threading\RunOnUIThread.cs" />
+    <Compile Include="Infrastructure\Threading\SynchronizationContextFactory.cs" />
+    <Compile Include="Infrastructure\Threading\SynchronizedCommand.cs" />
+    <Compile Include="Infrastructure\Threading\SynchronizedContext.cs" />
+    <Compile Include="Infrastructure\Threading\Synchronizer.cs" />
+    <Compile Include="Infrastructure\Threading\ThreadingExtensions.cs" />
+    <Compile Include="Infrastructure\Threading\TimerFactory.cs" />
+    <Compile Include="Infrastructure\Threading\TimerFactorySpecs.cs" />
+    <Compile Include="Infrastructure\Threading\WorkerThread.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="Infrastructure\Threading\WorkItem.cs" />
     <Compile Include="Infrastructure\Transactions\EmptyUnitOfWork.cs" />
     <Compile Include="Infrastructure\Transactions\UnitOfWork.cs" />
     <Compile Include="Infrastructure\Transactions\UnitOfWorkFactory.cs" />