Commit 2f7f173

mo <email@solidware.ca>
2011-02-21 23:57:59
fork momoney.
1 parent e978c3c
Changed files (191)
product
desktop.ui
infrastructure
specs
utility
product/desktop.ui/bootstrappers/AutofacDependencyRegistry.cs
@@ -0,0 +1,27 @@
+using System.Collections.Generic;
+using Autofac;
+using infrastructure.container;
+
+namespace desktop.ui.bootstrappers
+{
+    public class AutofacDependencyRegistry : DependencyRegistry
+    {
+        readonly IContainer container;
+
+        public AutofacDependencyRegistry(ContainerBuilder builder)
+        {
+            builder.Register(x => this).As<DependencyRegistry>().SingleInstance();
+            container = builder.Build();
+        }
+
+        public Contract get_a<Contract>()
+        {
+            return container.Resolve<Contract>();
+        }
+
+        public IEnumerable<Contract> get_all<Contract>()
+        {
+            return container.Resolve<IEnumerable<Contract>>();
+        }
+    }
+}
\ No newline at end of file
product/desktop.ui/bootstrappers/Bootstrapper.cs
@@ -0,0 +1,85 @@
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Windows.Threading;
+using Autofac;
+using desktop.ui.eventing;
+using desktop.ui.presenters;
+using desktop.ui.views;
+using infrastructure.container;
+using infrastructure.threading;
+using utility;
+
+namespace desktop.ui.bootstrappers
+{
+    public static class ClientBootstrapper
+    {
+        public static ShellWindow create_window()
+        {
+            var builder = new ContainerBuilder();
+
+            var shell_window = new ShellWindow();
+            builder.Register(x => shell_window).SingleInstance();
+            builder.Register(x => shell_window).As<RegionManager>().SingleInstance();
+
+            register_needs_startup(builder);
+
+            // infrastructure
+            //builder.Register<Log4NetLogFactory>().As<LogFactory>().SingleInstance();
+            builder.RegisterType<DefaultMapper>().As<Mapper>().SingleInstance();
+            //builder.RegisterGeneric(typeof (Mapper<,>));
+            builder.RegisterType<StubServiceBus>().As<ServiceBus>().SingleInstance();
+
+            register_presentation_infrastructure(builder);
+            register_presenters(builder);
+
+            shell_window.Closed += (o, e) => Resolve.the<CommandProcessor>().stop();
+            shell_window.Closed += (o, e) => Resolve.the<IEnumerable<NeedsShutdown>>();
+
+            Resolve.initialize_with(new AutofacDependencyRegistry(builder));
+            Resolve.the<IEnumerable<NeedStartup>>().each(x => x.run());
+            Resolve.the<CommandProcessor>().run();
+            return shell_window;
+        }
+
+        static void register_needs_startup(ContainerBuilder builder)
+        {
+            builder.RegisterType<ComposeShell>().As<NeedStartup>();
+            builder.RegisterType<ConfigureMappings>().As<NeedStartup>();
+        }
+
+        static void register_presentation_infrastructure(ContainerBuilder builder)
+        {
+            SynchronizationContext.SetSynchronizationContext(new DispatcherSynchronizationContext());
+            builder.RegisterType<WpfApplicationController>().As<ApplicationController>().SingleInstance();
+            builder.RegisterType<WPFPresenterFactory>().As<PresenterFactory>().SingleInstance();
+            builder.RegisterType<SynchronizedEventAggregator>().As<EventAggregator>().SingleInstance();
+            //builder.Register(x => AsyncOperationManager.SynchronizationContext);
+            builder.Register(x => SynchronizationContext.Current);
+            builder.RegisterType<AsynchronousCommandProcessor>().As<CommandProcessor>().SingleInstance();
+            //builder.Register<SynchronousCommandProcessor>().As<CommandProcessor>().SingleInstance();
+            builder.RegisterType<WPFCommandBuilder>().As<UICommandBuilder>();
+        }
+
+        static void register_presenters(ContainerBuilder builder)
+        {
+            builder.RegisterType<StatusBarPresenter>().SingleInstance();
+            builder.RegisterType<SelectedFamilyMemberPresenter>().SingleInstance();
+            builder.RegisterType<AddFamilyMemberPresenter>();
+            builder.RegisterType<AddFamilyMemberPresenter.SaveCommand>();
+            builder.RegisterType<AccountPresenter>();
+            builder.RegisterType<AccountPresenter.ImportTransactionCommand>();
+            builder.RegisterType<CancelCommand>();
+            builder.RegisterType<AddNewDetailAccountPresenter>();
+            builder.RegisterType<AddNewDetailAccountPresenter.CreateNewAccount>();
+        }
+    }
+
+    public class DefaultMapper : Mapper
+    {
+        public Output map_from<Input, Output>(Input item)
+        {
+            throw new NotImplementedException();
+        }
+    }
+}
\ No newline at end of file
product/desktop.ui/bootstrappers/ComposeShell.cs
@@ -0,0 +1,36 @@
+using desktop.ui.presenters;
+using desktop.ui.views;
+
+namespace desktop.ui.bootstrappers
+{
+    public class ComposeShell : NeedStartup
+    {
+        RegionManager region_manager;
+        ApplicationController controller;
+
+        public ComposeShell(RegionManager region_manager, ApplicationController controller)
+        {
+            this.region_manager = region_manager;
+            this.controller = controller;
+        }
+
+        public void run()
+        {
+            controller.add_tab<AccountPresenter, AccountTab>();
+
+            region_manager.region<MainMenu>(x =>
+            {
+                x.add("_Family").add("_Add Member", () =>
+                {
+                    controller.launch_dialog<AddFamilyMemberPresenter, AddFamilyMemberDialog>();
+                });
+                x.add("_Accounts").add("_Add Account", () => { 
+                    controller.launch_dialog<AddNewDetailAccountPresenter, AddNewDetailAccountDialog>();
+                });
+            });
+
+            controller.load_region<StatusBarPresenter, StatusBarRegion>();
+            controller.load_region<SelectedFamilyMemberPresenter, SelectedFamilyMemberRegion>();
+        }
+    }
+}
\ No newline at end of file
product/desktop.ui/bootstrappers/ConfigureMappings.cs
@@ -0,0 +1,9 @@
+namespace desktop.ui.bootstrappers
+{
+    public class ConfigureMappings : NeedStartup
+    {
+        public void run()
+        {
+        }
+    }
+}
\ No newline at end of file
product/desktop.ui/bootstrappers/NeedsShutdown.cs
@@ -0,0 +1,6 @@
+using utility;
+
+namespace desktop.ui.bootstrappers
+{
+    public interface NeedsShutdown : Command {}
+}
\ No newline at end of file
product/desktop.ui/bootstrappers/NeedStartup.cs
@@ -0,0 +1,6 @@
+using utility;
+
+namespace desktop.ui.bootstrappers
+{
+    public interface NeedStartup : Command {}
+}
\ No newline at end of file
product/desktop.ui/eventing/Event.cs
@@ -0,0 +1,6 @@
+namespace desktop.ui.eventing
+{
+    public interface Event
+    {
+    }
+}
\ No newline at end of file
product/desktop.ui/eventing/EventAggregator.cs
@@ -0,0 +1,13 @@
+using System;
+
+namespace desktop.ui.eventing
+{
+    public interface EventAggregator
+    {
+        void subscribe_to<Event>(EventSubscriber<Event> subscriber) where Event : eventing.Event;
+        void subscribe<Listener>(Listener subscriber);
+        void publish<Event>(Event the_event_to_broadcast) where Event : eventing.Event;
+        void publish<T>(Action<T> call) where T : class;
+        void publish<Event>() where Event : eventing.Event, new();
+    }
+}
\ No newline at end of file
product/desktop.ui/eventing/EventSubscriber.cs
@@ -0,0 +1,7 @@
+namespace desktop.ui.eventing
+{
+    public interface EventSubscriber<Event> where Event : eventing.Event
+    {
+        void notify(Event message);
+    }
+}
\ No newline at end of file
product/desktop.ui/SynchronizedEventAggregator.cs → product/desktop.ui/eventing/SynchronizedEventAggregator.cs
@@ -1,9 +1,10 @@
-using System;
+using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Threading;
+using utility;
 
-namespace desktop.ui
+namespace desktop.ui.eventing
 {
     public class SynchronizedEventAggregator : EventAggregator
     {
@@ -16,17 +17,17 @@ namespace desktop.ui
             this.context = context;
         }
 
-        public void subscribe_to<Event>(EventSubscriber<Event> subscriber) where Event : ui.Event
+        public void subscribe_to<Event>(EventSubscriber<Event> subscriber) where Event : eventing.Event
         {
-            register(subscriber);
+            subscribe(subscriber);
         }
 
-        public void register<Listener>(Listener subscriber) 
+        public void subscribe<Listener>(Listener subscriber) 
         {
             within_lock(() => subscribers.Add(subscriber));
         }
 
-        public void publish<Event>(Event the_event_to_broadcast) where Event : ui.Event
+        public void publish<Event>(Event the_event_to_broadcast) where Event : eventing.Event
         {
             var current_subscribers = subscribers.ToList();
             process(() => current_subscribers.call_on_each<EventSubscriber<Event>>(x => x.notify(the_event_to_broadcast)));
@@ -38,7 +39,7 @@ namespace desktop.ui
             process(() => current_subscribers.each(x => x.call_on(call)));
         }
 
-        public void publish<Event>() where Event : ui.Event, new()
+        public void publish<Event>() where Event : eventing.Event, new()
         {
             publish(new Event());
         }
product/desktop.ui/events/SelectedFamilyMember.cs
@@ -0,0 +1,10 @@
+using System;
+using desktop.ui.eventing;
+
+namespace desktop.ui.events
+{
+    public class SelectedFamilyMember : Event
+    {
+        public Guid id { get; set; }
+    }
+}
\ No newline at end of file
product/desktop.ui/events/UpdateOnLongRunningProcess.cs
@@ -0,0 +1,11 @@
+
+using desktop.ui.eventing;
+
+namespace desktop.ui.events
+{
+    public class UpdateOnLongRunningProcess : Event
+    {
+        public string message { get; set; }
+        public int percent_complete { get; set; }
+    }
+}
\ No newline at end of file
product/desktop.ui/presenters/AccountPresenter.cs
@@ -0,0 +1,38 @@
+namespace desktop.ui.presenters
+{
+    public class AccountPresenter : TabPresenter
+    {
+        UICommandBuilder ui_builder;
+
+        public AccountPresenter(UICommandBuilder ui_builder)
+        {
+            this.ui_builder = ui_builder;
+        }
+
+        public void present()
+        {
+            import = ui_builder.build<ImportTransactionCommand>(this);
+        }
+
+        public SelectedAccountDetails SelectedAccount { get; set; }
+
+        public IObservableCommand import { get; set; }
+
+        public string Header
+        {
+            get { return "Accounts"; }
+        }
+
+        public class ImportTransactionCommand : UICommand<AccountPresenter>
+        {
+            ApplicationController controller;
+
+            protected override void run(AccountPresenter presenter)
+            {
+                //controller.launch_dialog<ImportTransactionsPresenter, ImportTransactionDialog>(presenter.SelectedAccount);
+            }
+        }
+    }
+
+    public class SelectedAccountDetails {}
+}
\ No newline at end of file
product/desktop.ui/presenters/AddFamilyMemberPresenter.cs
@@ -0,0 +1,57 @@
+using System;
+using utility;
+
+namespace desktop.ui.presenters
+{
+    public class AddFamilyMemberPresenter : DialogPresenter
+    {
+        UICommandBuilder ui_builder;
+
+        public AddFamilyMemberPresenter(UICommandBuilder ui_builder)
+        {
+            this.ui_builder = ui_builder;
+        }
+
+        public void present()
+        {
+            Save = ui_builder.build<SaveCommand>(this);
+            Cancel = ui_builder.build<CancelCommand>(this);
+            date_of_birth = Clock.today();
+        }
+
+        public string first_name { get; set; }
+        public string last_name { get; set; }
+        public DateTime date_of_birth { get; set; }
+        public IObservableCommand Save { get; set; }
+        public IObservableCommand Cancel { get; set; }
+        public Action close { get; set; }
+
+        public class SaveCommand : UICommand<AddFamilyMemberPresenter>
+        {
+            ServiceBus bus;
+
+            public SaveCommand(ServiceBus bus)
+            {
+                this.bus = bus;
+            }
+
+            protected override void run(AddFamilyMemberPresenter presenter)
+            {
+                bus.publish<FamilyMemberToAdd>(x =>
+                {
+                    x.first_name = presenter.first_name;
+                    x.last_name = presenter.last_name;
+                    x.date_of_birth = presenter.date_of_birth;
+                });
+                presenter.close();
+            }
+        }
+    }
+
+    public class FamilyMemberToAdd
+    {
+        public string first_name { get; set; }
+        public string last_name { get; set; }
+        public DateTime date_of_birth { get; set; }
+    }
+}
\ No newline at end of file
product/desktop.ui/presenters/AddNewDetailAccountPresenter.cs
@@ -0,0 +1,56 @@
+using System;
+using System.Collections.Generic;
+
+namespace desktop.ui.presenters
+{
+    public class AddNewDetailAccountPresenter : DialogPresenter
+    {
+        UICommandBuilder builder;
+
+        public AddNewDetailAccountPresenter(UICommandBuilder builder)
+        {
+            this.builder = builder;
+        }
+
+        public void present()
+        {
+            add = builder.build<CreateNewAccount>(this);
+            cancel = builder.build<CancelCommand>(this);
+            currencies = new[] { "CAD" }.to_observable();
+        }
+
+        public string account_name { get; set; }
+        public string currency { get; set; }
+        public IEnumerable<string> currencies { get; set; }
+        public Action close { get; set; }
+        public IObservableCommand add { get; set; }
+        public IObservableCommand cancel { get; set; }
+
+        public class CreateNewAccount : UICommand<AddNewDetailAccountPresenter>
+        {
+            ServiceBus bus;
+
+            public CreateNewAccount(ServiceBus bus)
+            {
+                this.bus = bus;
+            }
+
+            protected override void run(AddNewDetailAccountPresenter presenter)
+            {
+                bus.publish<CreateNewDetailAccountCommand>(x =>
+                {
+                    x.account_name = presenter.account_name;
+                    x.currency = presenter.currency;
+                });
+                presenter.close();
+            }
+        }
+    }
+
+    public class CreateNewDetailAccountCommand
+    {
+        public string account_name { get; set; }
+
+        public string currency { get; set; }
+    }
+}
\ No newline at end of file
product/desktop.ui/presenters/PersonDetails.cs
@@ -0,0 +1,19 @@
+using System;
+using utility;
+
+namespace desktop.ui.presenters
+{
+    public class PersonDetails
+    {
+        public Guid id { get; set; }
+
+        public string first_name { get; set; }
+
+        public string last_name { get; set; }
+
+        public override string ToString()
+        {
+            return "{0} {1}".format(first_name, last_name);
+        }
+    }
+}
\ No newline at end of file
product/desktop.ui/presenters/SelectedFamilyMemberPresenter.cs
@@ -0,0 +1,56 @@
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using desktop.ui.eventing;
+using desktop.ui.events;
+using utility;
+
+namespace desktop.ui.presenters
+{
+    public class SelectedFamilyMemberPresenter : Observable<SelectedFamilyMemberPresenter>, Presenter, EventSubscriber<AddedNewFamilyMember>
+    {
+        PersonDetails selected_member;
+        EventAggregator event_aggregator;
+        Mapper mapper;
+        ServiceBus bus;
+
+        public SelectedFamilyMemberPresenter(EventAggregator event_aggregator, Mapper mapper, ServiceBus bus)
+        {
+            this.bus = bus;
+            this.mapper = mapper;
+            this.event_aggregator = event_aggregator;
+            family_members = new ObservableCollection<PersonDetails>();
+        }
+
+        public ICollection<PersonDetails> family_members { get; set; }
+
+        public PersonDetails SelectedMember
+        {
+            get { return selected_member; }
+            set
+            {
+                selected_member = value;
+                update(x => x.SelectedMember);
+                event_aggregator.publish(new SelectedFamilyMember {id = value.id});
+            }
+        }
+
+        public void present()
+        {
+            bus.publish<FindAllFamily>();
+        }
+
+        public void notify(AddedNewFamilyMember message)
+        {
+            family_members.Add(mapper.map_from<AddedNewFamilyMember, PersonDetails>(message));
+            update(x => x.family_members);
+        }
+    }
+
+    public class FindAllFamily
+    {
+    }
+
+    public class AddedNewFamilyMember : Event
+    {
+    }
+}
\ No newline at end of file
product/desktop.ui/presenters/StatusBarPresenter.cs
@@ -0,0 +1,27 @@
+using System.Threading;
+using desktop.ui.eventing;
+using desktop.ui.events;
+
+namespace desktop.ui.presenters
+{
+    public class StatusBarPresenter : Observable<StatusBarPresenter>, Presenter, EventSubscriber<UpdateOnLongRunningProcess>
+    {
+        public string progress_message { get; set; }
+        public bool is_progress_bar_on { get; set; }
+        public string username { get; set; }
+        public string title { get; set; }
+
+        public void present()
+        {
+            username = Thread.CurrentPrincipal.Identity.Name;
+            title = "N/A";
+        }
+
+        public void notify(UpdateOnLongRunningProcess message)
+        {
+            progress_message = message.message;
+            is_progress_bar_on = message.percent_complete < 100;
+            update(x => x.progress_message, x => x.is_progress_bar_on);
+        }
+    }
+}
\ No newline at end of file
product/desktop.ui/presenters/WpfBindingExtensinos.cs
@@ -0,0 +1,13 @@
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+
+namespace desktop.ui.presenters
+{
+    static public class WpfBindingExtensinos
+    {
+        static public ObservableCollection<T> to_observable<T>(this IEnumerable<T> items)
+        {
+            return new ObservableCollection<T>(items);
+        }
+    }
+}
\ No newline at end of file
product/desktop.ui/presenters/WpfCommandBuilder.cs
@@ -0,0 +1,23 @@
+using infrastructure.container;
+
+namespace desktop.ui.presenters
+{
+    public class WPFCommandBuilder : UICommandBuilder
+    {
+        DependencyRegistry container;
+
+        public WPFCommandBuilder(DependencyRegistry container)
+        {
+            this.container = container;
+        }
+
+        public IObservableCommand build<Command>(Presenter presenter) where Command : UICommand
+        {
+            var command = container.get_a<Command>();
+            return new SimpleCommand(() =>
+            {
+                command.run(presenter);
+            });
+        }
+    }
+}
\ No newline at end of file
product/desktop.ui/views/images/cancel.png
Binary file
product/desktop.ui/views/images/save.png
Binary file
product/desktop.ui/views/AccountTab.xaml
@@ -0,0 +1,8 @@
+<UserControl x:Class="desktop.ui.views.AccountTab"
+    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
+    <StackPanel>
+        <Label>Accounts</Label>
+        <Button Command="{Binding import}">Import Transactions</Button>
+    </StackPanel>
+</UserControl>
product/desktop.ui/views/AccountTab.xaml.cs
@@ -0,0 +1,12 @@
+using desktop.ui.presenters;
+
+namespace desktop.ui.views
+{
+    public partial class AccountTab : Tab<AccountPresenter>
+    {
+        public AccountTab()
+        {
+            InitializeComponent();
+        }
+    }
+}
\ No newline at end of file
product/desktop.ui/views/AddFamilyMemberDialog.xaml
@@ -0,0 +1,23 @@
+<Window x:Class="desktop.ui.views.AddFamilyMemberDialog"
+    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Add A Family Member" ShowInTaskbar="False" WindowStartupLocation="CenterScreen" Width="400" Height="170">
+    <DockPanel>
+        <StackPanel>
+        <Label FontWeight="Bold">Add A Family Member</Label>
+        <DockPanel>
+            <UniformGrid Rows="3">
+                <Label>first name</Label>
+                <TextBox Text="{Binding Path=first_name, Mode=TwoWay}"></TextBox>
+                <Label>last name</Label>
+                <TextBox Text="{Binding Path=last_name, Mode=TwoWay}"></TextBox>
+                <Label>date of birth</Label>
+                <DatePicker SelectedDate="{Binding Path=date_of_birth, Mode=TwoWay}"></DatePicker>
+            </UniformGrid>
+        </DockPanel>
+        <UniformGrid Rows="1" >
+            <Button Command="{Binding Save}" IsDefault="True">_Save</Button>
+            <Button Command="{Binding Cancel}" IsCancel="True">_Cancel</Button>
+        </UniformGrid>
+        </StackPanel>
+    </DockPanel>
+</Window>
product/desktop.ui/views/AddFamilyMemberDialog.xaml.cs
@@ -0,0 +1,19 @@
+using System.Windows;
+using desktop.ui.presenters;
+
+namespace desktop.ui.views
+{
+    public partial class AddFamilyMemberDialog : Dialog<AddFamilyMemberPresenter>
+    {
+        public AddFamilyMemberDialog()
+        {
+            InitializeComponent();
+        }
+
+        public void open()
+        {
+            Owner = Application.Current.MainWindow;
+            ShowDialog();
+        }
+    }
+}
\ No newline at end of file
product/desktop.ui/views/AddNewDetailAccountDialog.xaml
@@ -0,0 +1,27 @@
+<Window x:Class="desktop.ui.views.AddNewDetailAccountDialog" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:views="clr-namespace:desktop.ui.views" Title="Add New Detail Account">
+	<StackPanel>
+        <ListView HorizontalContentAlignment="Stretch" KeyboardNavigation.TabNavigation="Continue">
+            <ListView.ItemContainerStyle>
+                <Style TargetType="{x:Type ListViewItem}">
+                    <Setter Property="IsTabStop" Value="False" />
+                </Style>
+            </ListView.ItemContainerStyle>
+            <ListViewItem>
+                <DockPanel HorizontalAlignment="Stretch">
+                    <Label Width="150">Name:</Label>
+                    <TextBox HorizontalAlignment="Stretch" Text="{Binding Path=account_name}"/>
+                </DockPanel>
+            </ListViewItem>
+            <ListViewItem>
+                <DockPanel>
+                    <Label Width="150">Currency:</Label>
+                    <ComboBox SelectedItem="{Binding Path=currency}" ItemsSource="{Binding Path=currencies}"></ComboBox>
+                </DockPanel>
+            </ListViewItem>
+        </ListView>
+        <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
+            <views:ImageButton ImageSource="images\save.png" ToolTip="Add" Label="_Add" Command="{Binding Path=add}" IsDefault="True"/>
+        	<views:ImageButton ImageSource="images\cancel.png"  ToolTip="Cancel" Label="_Cancel" Command="{Binding Path=cancel}" IsCancel="True" />
+        </StackPanel>
+    </StackPanel>
+</Window>
\ No newline at end of file
product/desktop.ui/views/AddNewDetailAccountDialog.xaml.cs
@@ -0,0 +1,19 @@
+using System.Windows;
+using desktop.ui.presenters;
+
+namespace desktop.ui.views
+{
+    public partial class AddNewDetailAccountDialog : Dialog<AddNewDetailAccountPresenter>
+    {
+        public AddNewDetailAccountDialog()
+        {
+            InitializeComponent();
+        }
+
+        public void open()
+        {
+            Owner = Application.Current.MainWindow;
+            ShowDialog();
+        }
+    }
+}
\ No newline at end of file
product/desktop.ui/views/ErrorWindow.xaml
@@ -0,0 +1,11 @@
+<Window x:Class="desktop.ui.views.ErrorWindow"
+    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+    Title="Oops... I'm sorry but an un-expected error occurred." Width="600">
+    <DockPanel>
+        <Label DockPanel.Dock="Top" Content="{Binding Message}" />
+        <Expander>
+            <TextBlock Text="{Binding StackTrace}"></TextBlock>
+        </Expander>
+    </DockPanel>
+</Window>
product/desktop.ui/views/ErrorWindow.xaml.cs
@@ -0,0 +1,12 @@
+using System.Windows;
+
+namespace desktop.ui.views
+{
+    public partial class ErrorWindow : Window
+    {
+        public ErrorWindow()
+        {
+            InitializeComponent();
+        }
+    }
+}
\ No newline at end of file
product/desktop.ui/views/ImageButton.cs
@@ -0,0 +1,58 @@
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Media;
+
+namespace desktop.ui.views
+{
+    public class ImageButton : System.Windows.Controls.Button
+    {
+        public static readonly DependencyProperty ImageSourceProperty = DependencyProperty.Register("ImageSource", typeof(ImageSource), typeof(ImageButton));
+
+        public static readonly DependencyProperty LabelProperty = DependencyProperty.Register("Label", typeof(string),typeof (ImageButton));
+
+        public ImageSource ImageSource
+        {
+            get { return (ImageSource)GetValue(ImageSourceProperty); }
+            set{SetValue(ImageSourceProperty, value);}
+        }
+
+        public string Label
+        {
+            get { return (string) GetValue(LabelProperty); }
+            set{ SetValue(LabelProperty, value);}
+        }
+
+        private void Configure()
+        {
+            var binding = new Binding
+            {
+                RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(ImageButton), 1),
+                Path = new PropertyPath("IsEnabled")
+            };
+            var dataTrigger = new DataTrigger { Binding = binding, Value = false, Setters = { new Setter(OpacityProperty, 0.25) } };
+            var stackPanel = new StackPanel();
+            
+            stackPanel.Children.Add(new Image {Source = ImageSource, Style = new Style { Triggers = { dataTrigger } }, Height = 25, Margin = new Thickness(0)});
+            var label = new Label
+                              {
+                                  HorizontalAlignment = HorizontalAlignment.Center,
+                                  HorizontalContentAlignment = HorizontalAlignment.Left,
+                                  Margin = new Thickness(0),
+                                  Padding = new Thickness(0),
+                              };
+            if (!string.IsNullOrEmpty(Label))
+                label.Content = new AccessText{Text = Label, TextWrapping = TextWrapping.Wrap, Margin = new Thickness(0)};
+
+            stackPanel.Children.Add(label);
+            Content = stackPanel;
+        }
+
+        protected override void OnInitialized(System.EventArgs e)
+        {
+            base.OnInitialized(e);
+            Configure();
+            SetValue(ToolTipService.ShowOnDisabledProperty, true);
+        }
+    }
+}
\ No newline at end of file
product/desktop.ui/MainMenu.cs → product/desktop.ui/views/MainMenu.cs
@@ -1,6 +1,6 @@
 using System.Windows.Controls;
 
-namespace desktop.ui
+namespace desktop.ui.views
 {
     public class MainMenu : Menu
     {
product/desktop.ui/views/MenuItemExtensions.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Windows.Controls;
+
+namespace desktop.ui.views
+{
+    static public class MenuItemExtensions
+    {
+        static public MenuItem add(this MenuItem item, string header, Action action)
+        {
+            var menu_item = new MenuItem {Header = header, Command = new SimpleCommand(action)};
+            item.Items.Add(menu_item);
+            return menu_item;
+        }
+    }
+}
\ No newline at end of file
product/desktop.ui/views/SelectedFamilyMemberRegion.xaml
@@ -0,0 +1,18 @@
+<UserControl x:Class="desktop.ui.views.SelectedFamilyMemberRegion"
+    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" MinWidth="1024">
+<Expander>
+    <Expander.Header>
+        <DockPanel>
+        <Label>Family Member:</Label>
+        <ComboBox ItemsSource="{Binding family_members}" SelectedItem="{Binding SelectedMember}" Width="150"></ComboBox>
+        </DockPanel>
+    </Expander.Header>
+    <UniformGrid>
+        <Label FontWeight="Bold">First Name</Label>
+        <Label Content="{Binding Path=SelectedMember.first_name, Mode=OneWay}"/>
+        <Label FontWeight="Bold">Last Name</Label>
+        <Label Content="{Binding Path=SelectedMember.last_name, Mode=OneWay}"/>
+    </UniformGrid>
+</Expander>
+</UserControl>
product/desktop.ui/views/SelectedFamilyMemberRegion.xaml.cs
@@ -0,0 +1,12 @@
+using desktop.ui.presenters;
+
+namespace desktop.ui.views
+{
+    public partial class SelectedFamilyMemberRegion : View<SelectedFamilyMemberPresenter>
+    {
+        public SelectedFamilyMemberRegion()
+        {
+            InitializeComponent();
+        }
+    }
+}
\ No newline at end of file
product/desktop.ui/views/ShellWIndow.xaml
@@ -0,0 +1,10 @@
+<Window x:Class="desktop.ui.views.ShellWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ui="clr-namespace:desktop.ui.views" Title="MoMoney - (ALPHA)" MinWidth="1024" MinHeight="768" WindowStartupLocation="CenterScreen" WindowState="Maximized">
+	<DockPanel VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
+		<ui:MainMenu x:Name="Menu" DockPanel.Dock="Top" HorizontalAlignment="Right"></ui:MainMenu>
+		<ui:StatusBarRegion x:Name="StatusBar" DockPanel.Dock="Bottom"></ui:StatusBarRegion>
+		<StackPanel>
+			<ui:SelectedFamilyMemberRegion x:Name="SelectedFamilyMember"></ui:SelectedFamilyMemberRegion>
+			<TabControl Name="Tabs"></TabControl>
+		</StackPanel>
+	</DockPanel>
+</Window>
\ No newline at end of file
product/desktop.ui/views/ShellWIndow.xaml.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Windows;
+using utility;
+
+namespace desktop.ui.views
+{
+    public partial class ShellWindow : RegionManager
+    {
+        readonly IDictionary<Type, UIElement> regions;
+
+        public ShellWindow()
+        {
+            InitializeComponent();
+            regions = new Dictionary<Type, UIElement>
+                      {
+                          {GetType(), this},
+                          {typeof (Window), this},
+                          {Tabs.GetType(), Tabs},
+                          {StatusBar.GetType(), StatusBar},
+                          {Menu.GetType(), Menu},
+                          {SelectedFamilyMember.GetType(), SelectedFamilyMember},
+                      };
+        }
+
+        public void region<Region>(Action<Region> configure) where Region : UIElement
+        {
+            ensure_that_the_region_exists<Region>();
+            configure(regions[typeof (Region)].downcast_to<Region>());
+        }
+
+        void ensure_that_the_region_exists<Region>()
+        {
+            if (!regions.ContainsKey(typeof (Region)))
+                throw new Exception("Could not find region: {0}".format(typeof (Region)));
+        }
+    }
+}
\ No newline at end of file
product/desktop.ui/StatusBar.xaml → product/desktop.ui/views/StatusBarRegion.xaml
@@ -1,6 +1,6 @@
-<UserControl x:Class="desktop.ui.StatusBar"
-             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
-             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
+<UserControl x:Class="desktop.ui.views.StatusBarRegion"
+    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
     <StatusBar HorizontalAlignment="Right">
     	<StatusBar.Resources>
     		<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
product/desktop.ui/views/StatusBarRegion.xaml.cs
@@ -0,0 +1,12 @@
+using desktop.ui.presenters;
+
+namespace desktop.ui.views
+{
+    public partial class StatusBarRegion : View<StatusBarPresenter>
+    {
+        public StatusBarRegion()
+        {
+            InitializeComponent();
+        }
+    }
+}
\ No newline at end of file
product/desktop.ui/ApplicationController.cs
@@ -0,0 +1,11 @@
+using System.Windows;
+
+namespace desktop.ui
+{
+    public interface ApplicationController
+    {
+        void add_tab<Presenter, Tab>() where Presenter : TabPresenter where Tab : FrameworkElement, Tab<Presenter>, new();
+        void launch_dialog<Presenter, Dialog>() where Presenter : DialogPresenter where Dialog : FrameworkElement, Dialog<Presenter>, new();
+        void load_region<Presenter, Region>() where Presenter : ui.Presenter where Region : FrameworkElement, View<Presenter>, new();
+    }
+}
\ No newline at end of file
product/desktop.ui/CancelCommand.cs
@@ -0,0 +1,10 @@
+namespace desktop.ui
+{
+    public class CancelCommand : UICommand<DialogPresenter>
+    {
+        protected override void run(DialogPresenter presenter)
+        {
+            presenter.close();
+        }
+    }
+}
\ No newline at end of file
product/desktop.ui/Command.cs
@@ -1,88 +0,0 @@
-using System;
-
-namespace desktop.ui
-{
-    public interface Command
-    {
-        void run();
-    }
-
-    public interface Command<T>
-    {
-        void run(T item);
-    }
-
-    public static class CommandExtensions
-    {
-        public static ui.Command then<Command>(this Command left) where Command : ui.Command, new()
-        {
-            return then(left, new Command());
-        }
-
-        public static Command then(this Command left, Command right)
-        {
-            return new ChainedCommand(left, right);
-        }
-
-        public static Command then(this Command left, Action right)
-        {
-            return new ChainedCommand(left, new AnonymousCommand(right));
-        }
-
-        public static Command<T> then<T>(this Command<T> left, Command<T> right)
-        {
-            return new ChainedCommand<T>(left, right);
-        }
-    }
-
-    public class ChainedCommand : Command
-    {
-        readonly Command left;
-        readonly Command right;
-
-        public ChainedCommand(Command left, Command right)
-        {
-            this.left = left;
-            this.right = right;
-        }
-
-        public void run()
-        {
-            left.run();
-            right.run();
-        }
-    }
-
-    public class AnonymousCommand : Command
-    {
-        readonly Action action;
-
-        public AnonymousCommand(Action action)
-        {
-            this.action = action;
-        }
-
-        public void run()
-        {
-            action();
-        }
-    }
-
-    public class ChainedCommand<T> : Command<T>
-    {
-        Command<T> left;
-        Command<T> right;
-
-        public ChainedCommand(Command<T> left, Command<T> right)
-        {
-            this.left = left;
-            this.right = right;
-        }
-
-        public void run(T item)
-        {
-            left.run(item);
-            right.run(item);
-        }
-    }
-}
\ No newline at end of file
product/desktop.ui/ConfigureContainerCommand.cs
@@ -1,23 +0,0 @@
-using System.Threading;
-using System.Windows.Threading;
-using Autofac;
-
-namespace desktop.ui
-{
-    public class ConfigureContainerCommand : Command
-    {
-        public void run()
-        {
-            var builder = new ContainerBuilder();
-            var window = new ShellWindow();
-
-            builder.Register(x => window).As<IRegionManager>().As<ShellWindow>().SingleInstance();
-            builder.RegisterType<WPFApplicationController>().As<IApplicationController>().SingleInstance();
-            //builder.RegisterAssemblyTypes(GetType().Assembly);
-            SynchronizationContext.SetSynchronizationContext(new DispatcherSynchronizationContext());
-            builder.Register(x => SynchronizationContext.Current);
-
-            IOC.BindTo(builder.Build());
-        }
-    }
-}
\ No newline at end of file
product/desktop.ui/desktop.ui.csproj
@@ -56,38 +56,73 @@
     <Reference Include="PresentationFramework" />
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="Iterating.cs" />
-    <Compile Include="IApplicationController.cs" />
-    <Compile Include="Command.cs" />
-    <Compile Include="ConfigureContainerCommand.cs" />
-    <Compile Include="ConversionExtensions.cs" />
-    <Compile Include="EventAggregator.cs" />
-    <Compile Include="IOC.cs" />
-    <Compile Include="MainMenu.cs" />
-    <Compile Include="StartAllModules.cs" />
-    <Compile Include="StatusBar.xaml.cs">
-      <DependentUpon>StatusBar.xaml</DependentUpon>
+    <Compile Include="ApplicationController.cs" />
+    <Compile Include="bootstrappers\AutofacDependencyRegistry.cs" />
+    <Compile Include="bootstrappers\Bootstrapper.cs" />
+    <Compile Include="bootstrappers\ComposeShell.cs" />
+    <Compile Include="bootstrappers\ConfigureMappings.cs" />
+    <Compile Include="bootstrappers\NeedsShutdown.cs" />
+    <Compile Include="bootstrappers\NeedStartup.cs" />
+    <Compile Include="CancelCommand.cs" />
+    <Compile Include="Dialog.cs" />
+    <Compile Include="DialogPresenter.cs" />
+    <Compile Include="eventing\Event.cs" />
+    <Compile Include="eventing\EventAggregator.cs" />
+    <Compile Include="eventing\EventSubscriber.cs" />
+    <Compile Include="eventing\SynchronizedEventAggregator.cs" />
+    <Compile Include="events\SelectedFamilyMember.cs" />
+    <Compile Include="events\UpdateOnLongRunningProcess.cs" />
+    <Compile Include="IObservableCommand.cs" />
+    <Compile Include="Observable.cs" />
+    <Compile Include="Presenter.cs" />
+    <Compile Include="PresenterFactory.cs" />
+    <Compile Include="presenters\AccountPresenter.cs" />
+    <Compile Include="presenters\AddFamilyMemberPresenter.cs" />
+    <Compile Include="presenters\AddNewDetailAccountPresenter.cs" />
+    <Compile Include="presenters\PersonDetails.cs" />
+    <Compile Include="presenters\SelectedFamilyMemberPresenter.cs" />
+    <Compile Include="ServiceBus.cs" />
+    <Compile Include="presenters\StatusBarPresenter.cs" />
+    <Compile Include="presenters\WpfBindingExtensinos.cs" />
+    <Compile Include="presenters\WpfCommandBuilder.cs" />
+    <Compile Include="Program.cs" />
+    <Compile Include="SimpleCommand.cs" />
+    <Compile Include="StubServiceBus.cs" />
+    <Compile Include="Tab.cs" />
+    <Compile Include="TabPresenter.cs" />
+    <Compile Include="UICommand.cs" />
+    <Compile Include="UICommandBuilder.cs" />
+    <Compile Include="View.cs" />
+    <Compile Include="views\AccountTab.xaml.cs">
+      <DependentUpon>AccountTab.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="views\AddFamilyMemberDialog.xaml.cs">
+      <DependentUpon>AddFamilyMemberDialog.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="views\AddNewDetailAccountDialog.xaml.cs">
+      <DependentUpon>AddNewDetailAccountDialog.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="views\ErrorWindow.xaml.cs">
+      <DependentUpon>ErrorWindow.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="views\ImageButton.cs" />
+    <Compile Include="views\MainMenu.cs" />
+    <Compile Include="views\MenuItemExtensions.cs" />
+    <Compile Include="views\SelectedFamilyMemberRegion.xaml.cs">
+      <DependentUpon>SelectedFamilyMemberRegion.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="views\ShellWIndow.xaml.cs">
+      <DependentUpon>ShellWIndow.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="views\StatusBarRegion.xaml.cs">
+      <DependentUpon>StatusBarRegion.xaml</DependentUpon>
     </Compile>
-    <Compile Include="StringExtensions.cs" />
-    <Compile Include="SynchronizedEventAggregator.cs" />
     <Compile Include="WPFApplication.cs" />
     <Compile Include="WPFApplicationController.cs" />
-    <Page Include="ShellWindow.xaml">
-      <Generator>MSBuild:Compile</Generator>
-      <SubType>Designer</SubType>
-    </Page>
     <Compile Include="RegionManager.cs" />
-    <Compile Include="ShellWindow.xaml.cs">
-      <DependentUpon>ShellWindow.xaml</DependentUpon>
-      <SubType>Code</SubType>
-    </Compile>
-    <Page Include="StatusBar.xaml">
-      <SubType>Designer</SubType>
-      <Generator>MSBuild:Compile</Generator>
-    </Page>
+    <Compile Include="WPFPresenterFactory.cs" />
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="Program.cs" />
     <Compile Include="Properties\AssemblyInfo.cs">
       <SubType>Code</SubType>
     </Compile>
@@ -111,6 +146,50 @@
     </None>
     <AppDesigner Include="Properties\" />
   </ItemGroup>
+  <ItemGroup>
+    <Page Include="views\AccountTab.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
+    <Page Include="views\AddFamilyMemberDialog.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
+    <Page Include="views\AddNewDetailAccountDialog.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
+    <Page Include="views\ErrorWindow.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
+    <Page Include="views\SelectedFamilyMemberRegion.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
+    <Page Include="views\ShellWIndow.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
+    <Page Include="views\StatusBarRegion.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="views\images\cancel.png" />
+    <Resource Include="views\images\save.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\infrastructure\infrastructure.csproj">
+      <Project>{CC006EB6-4E3C-4497-B8CC-5CAF54E40113}</Project>
+      <Name>infrastructure</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\utility\utility.csproj">
+      <Project>{39B95E47-DA9C-4C80-A395-515600C55D4B}</Project>
+      <Name>utility</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. 
        Other similar extension points exist, see Microsoft.Common.targets.
product/desktop.ui/Dialog.cs
@@ -0,0 +1,8 @@
+namespace desktop.ui
+{
+    public interface Dialog<TPresenter> : View<TPresenter> where TPresenter : DialogPresenter
+    {
+        void open();
+        void Close();
+    }
+}
\ No newline at end of file
product/desktop.ui/DialogPresenter.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace desktop.ui
+{
+    public interface DialogPresenter : Presenter
+    {
+        Action close { get; set; }
+    }
+}
\ No newline at end of file
product/desktop.ui/EventAggregator.cs
@@ -1,22 +0,0 @@
-using System;
-
-namespace desktop.ui
-{
-    public interface EventAggregator
-    {
-        void subscribe_to<Event>(EventSubscriber<Event> subscriber) where Event : ui.Event;
-        void register<Listener>(Listener listener);
-        void publish<Event>(Event the_event_to_broadcast) where Event : ui.Event;
-        void publish<T>(Action<T> call) where T : class;
-        void publish<Event>() where Event : ui.Event, new();
-    }
-
-    public interface EventSubscriber<Event> where Event : ui.Event
-    {
-        void notify(Event message);
-    }
-
-    public interface Event
-    {
-    }
-}
\ No newline at end of file
product/desktop.ui/IApplicationController.cs
@@ -1,7 +0,0 @@
-namespace desktop.ui
-{
-    public interface IApplicationController
-    {
-        void start();
-    }
-}
\ No newline at end of file
product/desktop.ui/IObservableCommand.cs
@@ -0,0 +1,9 @@
+using System.Windows.Input;
+
+namespace desktop.ui
+{
+    public interface IObservableCommand : ICommand
+    {
+        void notify_observers();
+    }
+}
\ No newline at end of file
product/desktop.ui/IOC.cs
@@ -1,19 +0,0 @@
-using Autofac;
-
-namespace desktop.ui
-{
-    public static class IOC
-    {
-        static IContainer container;
-
-        public static void BindTo(IContainer container)
-        {
-            IOC.container = container;
-        }
-
-        public static T Resolve<T>()
-        {
-            return container.Resolve<T>();
-        }
-    }
-}
\ No newline at end of file
product/desktop.ui/Observable.cs
@@ -0,0 +1,20 @@
+using System;
+using System.ComponentModel;
+using System.Linq.Expressions;
+using utility;
+
+namespace desktop.ui
+{
+    public abstract class Observable<T> : INotifyPropertyChanged
+    {
+        public event PropertyChangedEventHandler PropertyChanged = (o, e) => {};
+
+        protected void update(params Expression<Func<T, object>>[] properties)
+        {
+            properties.each(x =>
+            {
+                PropertyChanged(this, new PropertyChangedEventArgs(x.pick_property().Name));
+            });
+        }
+    }
+}
\ No newline at end of file
product/desktop.ui/Presenter.cs
@@ -0,0 +1,7 @@
+namespace desktop.ui
+{
+    public interface Presenter
+    {
+        void present();
+    }
+}
\ No newline at end of file
product/desktop.ui/PresenterFactory.cs
@@ -0,0 +1,7 @@
+namespace desktop.ui
+{
+    public interface PresenterFactory
+    {
+        T create<T>() where T : Presenter;
+    }
+}
\ No newline at end of file
product/desktop.ui/Program.cs
@@ -1,24 +1,33 @@
-using System;
+using System;
 using System.Security.Principal;
+using System.Windows;
 using System.Windows.Threading;
+using desktop.ui.bootstrappers;
+using desktop.ui.views;
+using infrastructure.logging;
 
 namespace desktop.ui
 {
-    public class Program
+    static public class Program
     {
         [STAThread]
-        public static void Main(string[] args)
+        static public void Main(string[] args)
         {
-            AppDomain.CurrentDomain.UnhandledException += (o, e) => { };
+            AppDomain.CurrentDomain.UnhandledException += (o, e) =>
+            {
+                (e.ExceptionObject as Exception).add_to_log();
+            };
             AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
-            Dispatcher.CurrentDispatcher.UnhandledException += (o, e) => { };
-
-            new ConfigureContainerCommand()
-                .then(() => { Console.Out.WriteLine("starting"); })
-                .then(() => { IOC.Resolve<IApplicationController>().start(); })
-                .run();
-            
-            new WPFApplication().Run(IOC.Resolve<ShellWindow>());
+            Dispatcher.CurrentDispatcher.UnhandledException += (o, e) =>
+            {
+                e.Exception.add_to_log();
+                new ErrorWindow {DataContext = e.Exception}.ShowDialog();
+                e.Handled = true;
+            };
+            new WPFApplication
+            {
+                ShutdownMode = ShutdownMode.OnMainWindowClose,
+            }.Run(ClientBootstrapper.create_window());
         }
     }
 }
\ No newline at end of file
product/desktop.ui/RegionManager.cs
@@ -1,10 +1,10 @@
-using System;
+using System;
 using System.Windows;
 
 namespace desktop.ui
 {
-    public interface IRegionManager
+    public interface RegionManager
     {
-        void Region<Control>(Action<Control> configure) where Control : UIElement;
+        void region<Control>(Action<Control> configure) where Control : UIElement;
     }
 }
\ No newline at end of file
product/desktop.ui/ServiceBus.cs
@@ -0,0 +1,11 @@
+using System;
+
+namespace desktop.ui
+{
+    public interface ServiceBus
+    {
+        void publish<Message>() where Message : new();
+        void publish<Message>(Message item) where Message : new();
+        void publish<Message>(Action<Message> configure) where Message : new();
+    }
+}
\ No newline at end of file
product/desktop.ui/ShellWindow.xaml
@@ -1,11 +0,0 @@
-<Window x:Class="desktop.ui.ShellWindow"
-        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
-        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ui="clr-namespace:desktop.ui" Title="RRSP Contributions">
-	<DockPanel VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
-		<ui:MainMenu x:Name="Menu" DockPanel.Dock="Top" HorizontalAlignment="Right"></ui:MainMenu>
-		<ui:StatusBar x:Name="StatusBar" DockPanel.Dock="Bottom"></ui:StatusBar>
-		<StackPanel>
-			<TabControl Name="Tabs"></TabControl>
-		</StackPanel>
-	</DockPanel>
-</Window>
product/desktop.ui/ShellWindow.xaml.cs
@@ -1,36 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Windows;
-
-namespace desktop.ui
-{
-    public partial class ShellWindow : IRegionManager
-    {
-        private IDictionary<Type, UIElement> regions;
-
-        public ShellWindow()
-        {
-            InitializeComponent();
-            regions = new Dictionary<Type, UIElement>
-                          {
-                              {GetType(), this},
-                              {typeof (Window), this},
-                              {Menu.GetType(), Menu},
-                              {StatusBar.GetType(), StatusBar},
-                              {Tabs.GetType(), Tabs},
-                          };
-        }
-
-        public void Region<Control>(Action<Control> configure) where Control : UIElement
-        {
-            ensure_that_the_region_exists<Control>();
-            configure(regions[typeof (Control)].downcast_to<Control>());
-        }
-
-        private void ensure_that_the_region_exists<Region>()
-        {
-            if (!regions.ContainsKey(typeof (Region)))
-                throw new Exception("Could not find region: {0}".format(typeof (Region)));
-        }
-    }
-}
\ No newline at end of file
product/desktop.ui/SimpleCommand.cs
@@ -0,0 +1,35 @@
+using System;
+
+namespace desktop.ui
+{
+    public class SimpleCommand : IObservableCommand
+    {
+        Action action = () => {};
+        Func<bool> predicate;
+
+        public SimpleCommand(Action action) : this(action, () => true) {}
+
+        public SimpleCommand(Action action, Func<bool> predicate)
+        {
+            this.action = action ?? (() => {});
+            this.predicate = predicate ?? (() => true);
+        }
+
+        public event EventHandler CanExecuteChanged = (o, e) => {};
+
+        public void Execute(object parameter)
+        {
+            action();
+        }
+
+        public bool CanExecute(object parameter)
+        {
+            return predicate();
+        }
+
+        public void notify_observers()
+        {
+            CanExecuteChanged(this, EventArgs.Empty);
+        }
+    }
+}
\ No newline at end of file
product/desktop.ui/StartAllModules.cs
@@ -1,7 +0,0 @@
-namespace desktop.ui
-{
-    public interface IStartAllModules
-    {
-        void run(IRegionManager regionManager);
-    }
-}
\ No newline at end of file
product/desktop.ui/StatusBar.xaml.cs
@@ -1,27 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Data;
-using System.Windows.Documents;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Imaging;
-using System.Windows.Navigation;
-using System.Windows.Shapes;
-
-namespace desktop.ui
-{
-    /// <summary>
-    /// Interaction logic for StatusBar.xaml
-    /// </summary>
-    public partial class StatusBar : UserControl
-    {
-        public StatusBar()
-        {
-            InitializeComponent();
-        }
-    }
-}
product/desktop.ui/StubServiceBus.cs
@@ -0,0 +1,19 @@
+using System;
+
+namespace desktop.ui
+{
+    public class StubServiceBus : ServiceBus
+    {
+        public void publish<Message>() where Message : new()
+        {
+        }
+
+        public void publish<Message>(Message item) where Message : new()
+        {
+        }
+
+        public void publish<Message>(Action<Message> configure) where Message : new()
+        {
+        }
+    }
+}
\ No newline at end of file
product/desktop.ui/Tab.cs
@@ -0,0 +1,4 @@
+namespace desktop.ui
+{
+    public interface Tab<Presenter> : View<Presenter> where Presenter : TabPresenter {}
+}
\ No newline at end of file
product/desktop.ui/TabPresenter.cs
@@ -0,0 +1,7 @@
+namespace desktop.ui
+{
+    public interface TabPresenter : Presenter
+    {
+        string Header { get; }
+    }
+}
\ No newline at end of file
product/desktop.ui/UICommand.cs
@@ -0,0 +1,17 @@
+namespace desktop.ui
+{
+    public interface UICommand
+    {
+        void run<T>(T presenter) where T : Presenter;
+    }
+
+    public abstract class UICommand<T> : UICommand where T : class, Presenter
+    {
+        void UICommand.run<T1>(T1 presenter)
+        {
+            run(presenter as T);
+        }
+
+        protected abstract void run(T presenter);
+    }
+}
\ No newline at end of file
product/desktop.ui/UICommandBuilder.cs
@@ -0,0 +1,7 @@
+namespace desktop.ui
+{
+    public interface UICommandBuilder
+    {
+        IObservableCommand build<T>(Presenter presenter) where T : UICommand;
+    }
+}
\ No newline at end of file
product/desktop.ui/View.cs
@@ -0,0 +1,4 @@
+namespace desktop.ui
+{
+    public interface View<TPresenter> where TPresenter : Presenter {}
+}
\ No newline at end of file
product/desktop.ui/WPFApplication.cs
@@ -1,14 +1,6 @@
-using System;
-using System.Security.Principal;
-using System.Windows;
+using System.Windows;
 
 namespace desktop.ui
 {
-    public class WPFApplication : Application
-    {
-        public WPFApplication()
-        {
-            ShutdownMode = ShutdownMode.OnMainWindowClose;
-        }
-    }
+    public class WPFApplication : Application {}
 }
\ No newline at end of file
product/desktop.ui/WPFApplicationController.cs
@@ -1,23 +1,55 @@
-namespace desktop.ui
+using System.Windows;
+using System.Windows.Controls;
+using desktop.ui.eventing;
+
+namespace desktop.ui
 {
-    public class WPFApplicationController : IApplicationController
+    public class WpfApplicationController : ApplicationController
     {
-        readonly IStartAllModules startAllModules;
-        readonly EventAggregator eventAggregator;
-        readonly IRegionManager regionManager;
+        RegionManager region_manager;
+        PresenterFactory factory;
+        EventAggregator event_aggregator;
+
+        public WpfApplicationController(RegionManager region_manager, PresenterFactory factory, EventAggregator event_aggregator)
+        {
+            this.region_manager = region_manager;
+            this.event_aggregator = event_aggregator;
+            this.factory = factory;
+        }
+
+        public void add_tab<Presenter, View>() where Presenter : TabPresenter where View : FrameworkElement, Tab<Presenter>, new()
+        {
+            var presenter = factory.create<Presenter>();
+            event_aggregator.subscribe(presenter);
+            presenter.present();
+            region_manager.region<TabControl>(x => x.Items.Add(new TabItem
+                                                               {
+                                                                   Header = presenter.Header,
+                                                                   Content = new View {DataContext = presenter}
+                                                               }));
+        }
 
-        public WPFApplicationController(IStartAllModules startAllModules, EventAggregator eventAggregator,
-                                        IRegionManager regionManager)
+        public void launch_dialog<Presenter, Dialog>() where Presenter : DialogPresenter where Dialog : FrameworkElement, Dialog<Presenter>, new()
         {
-            this.startAllModules = startAllModules;
-            this.eventAggregator = eventAggregator;
-            this.regionManager = regionManager;
+            var presenter = factory.create<Presenter>();
+            var dialog = new Dialog {DataContext = presenter};
+            presenter.close = () =>
+            {
+                dialog.Close();
+            };
+            presenter.present();
+            dialog.open();
         }
 
-        public void start()
+        public void load_region<Presenter, Region>() where Presenter : ui.Presenter where Region : FrameworkElement, View<Presenter>, new()
         {
-            startAllModules.run(regionManager);
-            eventAggregator.register(this);
+            var presenter = factory.create<Presenter>();
+            event_aggregator.subscribe(presenter);
+            presenter.present();
+            region_manager.region<Region>(x =>
+            {
+                x.DataContext = presenter;
+            });
         }
     }
 }
\ No newline at end of file
product/desktop.ui/WPFPresenterFactory.cs
@@ -0,0 +1,19 @@
+using infrastructure.container;
+
+namespace desktop.ui
+{
+    public class WPFPresenterFactory : PresenterFactory
+    {
+        DependencyRegistry container;
+
+        public WPFPresenterFactory(DependencyRegistry container)
+        {
+            this.container = container;
+        }
+
+        public T create<T>() where T : Presenter
+        {
+            return container.get_a<T>();
+        }
+    }
+}
\ No newline at end of file
product/infrastructure/cloning/BinarySerializer.cs
@@ -0,0 +1,11 @@
+using System.Runtime.Serialization.Formatters.Binary;
+
+namespace infrastructure.cloning
+{
+    public class BinarySerializer<T> : FileStreamSerializer<T>
+    {
+        public BinarySerializer(string file_path) : base(file_path, new BinaryFormatter())
+        {
+        }
+    }
+}
\ No newline at end of file
product/infrastructure/cloning/FileStreamSerializer.cs
@@ -0,0 +1,34 @@
+using System.IO;
+using System.Runtime.Serialization;
+
+namespace infrastructure.cloning
+{
+    public class FileStreamSerializer<T> : Serializer<T>
+    {
+        public FileStreamSerializer(string file_path, IFormatter formatter)
+        {
+            this.file_path = file_path;
+            this.formatter = formatter;
+        }
+
+        public void serialize(T to_serialize)
+        {
+            using (var stream = new FileStream(file_path, FileMode.Create, FileAccess.Write))
+                formatter.Serialize(stream, to_serialize);
+        }
+
+        public T deserialize()
+        {
+            using (var stream = new FileStream(file_path, FileMode.Open, FileAccess.Read))
+                return (T) formatter.Deserialize(stream);
+        }
+
+        public void Dispose()
+        {
+            File.Delete(file_path);
+        }
+
+        readonly string file_path;
+        readonly IFormatter formatter;
+    }
+}
\ No newline at end of file
product/infrastructure/cloning/Prototype.cs
@@ -0,0 +1,21 @@
+using System.IO;
+
+namespace infrastructure.cloning
+{
+    public interface IPrototype
+    {
+        T clone<T>(T item);
+    }
+
+    public class Prototype : IPrototype
+    {
+        public T clone<T>(T item)
+        {
+            using (var serializer = new BinarySerializer<T>(Path.GetTempFileName()))
+            {
+                serializer.serialize(item);
+                return serializer.deserialize();
+            }
+        }
+    }
+}
\ No newline at end of file
product/infrastructure/cloning/Serializer.cs
@@ -0,0 +1,10 @@
+using System;
+
+namespace infrastructure.cloning
+{
+    public interface Serializer<T> : IDisposable
+    {
+        void serialize(T to_serialize);
+        T deserialize();
+    }
+}
\ No newline at end of file
product/infrastructure/container/DependencyRegistry.cs
@@ -0,0 +1,10 @@
+using System.Collections.Generic;
+
+namespace infrastructure.container
+{
+    public interface DependencyRegistry
+    {
+        Contract get_a<Contract>();
+        IEnumerable<Contract> get_all<Contract>();
+    }
+}
\ No newline at end of file
product/infrastructure/container/DependencyResolutionException.cs
@@ -0,0 +1,13 @@
+using System;
+using utility;
+
+namespace infrastructure.container
+{
+    public class DependencyResolutionException<T> : Exception
+    {
+        public DependencyResolutionException(Exception inner_exception)
+            : base("Could not resolve {0}".format(typeof (T).FullName), inner_exception)
+        {
+        }
+    }
+}
\ No newline at end of file
product/infrastructure/container/Resolve.cs
@@ -0,0 +1,31 @@
+using System;
+
+namespace infrastructure.container
+{
+    static public class Resolve
+    {
+        static DependencyRegistry underlying_registry;
+
+        static public void initialize_with(DependencyRegistry registry)
+        {
+            underlying_registry = registry;
+        }
+
+        static public DependencyToResolve the<DependencyToResolve>()
+        {
+            try
+            {
+                return underlying_registry.get_a<DependencyToResolve>();
+            }
+            catch (Exception e)
+            {
+                throw new DependencyResolutionException<DependencyToResolve>(e);
+            }
+        }
+
+        static public bool is_initialized()
+        {
+            return underlying_registry != null;
+        }
+    }
+}
\ No newline at end of file
product/infrastructure/debugging/Launch.cs
@@ -0,0 +1,15 @@
+using System.Diagnostics;
+
+namespace infrastructure.debugging
+{
+    static public class Launch
+    {
+        static public void the_debugger()
+        {
+#if DEBUG
+            if (Debugger.IsAttached) Debugger.Break();
+            else Debugger.Launch();
+#endif
+        }
+    }
+}
\ No newline at end of file
product/infrastructure/filesystem/ApplicationFile.cs
@@ -0,0 +1,62 @@
+namespace infrastructure.filesystem
+{
+    public class ApplicationFile : File
+    {
+        public ApplicationFile(string path)
+        {
+            this.path = path;
+        }
+
+        public virtual string path { get; private set; }
+
+        public virtual bool does_the_file_exist()
+        {
+            return !string.IsNullOrEmpty(path) && System.IO.File.Exists(path);
+        }
+
+        public void copy_to(string other_path)
+        {
+            System.IO.File.Copy(path, other_path, true);
+        }
+
+        public void delete()
+        {
+            System.IO.File.Delete(path);
+        }
+
+        public static implicit operator ApplicationFile(string file_path)
+        {
+            return new ApplicationFile(file_path);
+        }
+
+        public static implicit operator string(ApplicationFile file)
+        {
+            return file.path;
+        }
+
+        public bool Equals(ApplicationFile other)
+        {
+            if (ReferenceEquals(null, other)) return false;
+            if (ReferenceEquals(this, other)) return true;
+            return Equals(other.path, path);
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != typeof (ApplicationFile)) return false;
+            return Equals((ApplicationFile) obj);
+        }
+
+        public override int GetHashCode()
+        {
+            return (path != null ? path.GetHashCode() : 0);
+        }
+
+        public override string ToString()
+        {
+            return path;
+        }
+    }
+}
\ No newline at end of file
product/infrastructure/filesystem/File.cs
@@ -0,0 +1,10 @@
+namespace infrastructure.filesystem
+{
+    public interface File
+    {
+        string path { get; }
+        bool does_the_file_exist();
+        void copy_to(string path);
+        void delete();
+    }
+}
\ No newline at end of file
product/infrastructure/logging/Log.cs
@@ -0,0 +1,25 @@
+using System;
+using infrastructure.container;
+
+namespace infrastructure.logging
+{
+    static public class Log
+    {
+        static public Logger For<T>(T item_to_create_logger_for)
+        {
+            return For(typeof (T));
+        }
+
+        static public Logger For(Type type_to_create_a_logger_for)
+        {
+            try
+            {
+                return Resolve.the<LogFactory>().create_for(type_to_create_a_logger_for);
+            }
+            catch
+            {
+                return new TextLogger(Console.Out);
+            }
+        }
+    }
+}
\ No newline at end of file
product/infrastructure/logging/LogFactory.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace infrastructure.logging
+{
+    public interface LogFactory
+    {
+        Logger create_for(Type type_to_create_logger_for);
+    }
+}
\ No newline at end of file
product/infrastructure/logging/Loggable.cs
@@ -0,0 +1,7 @@
+namespace infrastructure.logging
+{
+    public interface Loggable
+    {
+        
+    }
+}
\ No newline at end of file
product/infrastructure/logging/Logger.cs
@@ -0,0 +1,11 @@
+using System;
+
+namespace infrastructure.logging
+{
+    public interface Logger
+    {
+        void informational(string formatted_string, params object[] arguments);
+        void debug(string formatted_string, params object[] arguments);
+        void error(Exception e);
+    }
+}
\ No newline at end of file
product/infrastructure/logging/LoggingExtensions.cs
@@ -0,0 +1,17 @@
+using System;
+
+namespace infrastructure.logging
+{
+    public static class LoggingExtensions
+    {
+        public static Logger log<T>(this T item_to_log)
+        {
+            return Log.For(item_to_log);
+        }
+
+        public static void add_to_log(this Exception error_to_log)
+        {
+            Log.For(error_to_log).error(error_to_log);
+        }
+    }
+}
\ No newline at end of file
product/infrastructure/logging/TextLogger.cs
@@ -0,0 +1,33 @@
+using System;
+using System.IO;
+using System.Threading;
+using utility;
+
+namespace infrastructure.logging
+{
+    public class TextLogger : Logger
+    {
+        readonly TextWriter writer;
+
+        public TextLogger(TextWriter writer)
+        {
+            this.writer = writer;
+        }
+
+        public void informational(string formatted_string, params object[] arguments)
+        {
+            writer.WriteLine(formatted_string, arguments);
+        }
+
+        public void debug(string formatted_string, params object[] arguments)
+        {
+            writer.WriteLine("[{0}] - {1}", Thread.CurrentThread.ManagedThreadId,
+                             formatted_string.format(arguments));
+        }
+
+        public void error(Exception e)
+        {
+            writer.WriteLine("{0}", e);
+        }
+    }
+}
\ No newline at end of file
product/infrastructure/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("infrastructure")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("infrastructure")]
+[assembly: AssemblyCopyright("Copyright ©  2011")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("c400224d-0e9e-4936-aabb-c4711ec81f1a")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
product/infrastructure/proxies/ExceptionExtensions.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Reflection;
+
+namespace infrastructure.proxies
+{
+    static public class ExceptionExtensions
+    {
+        static readonly MethodInfo method =
+            typeof (Exception).GetMethod("InternalPreserveStackTrace",
+                                         BindingFlags.NonPublic | BindingFlags.Instance);
+
+        static public Exception preserve_stack_trace(this Exception exception)
+        {
+            method.Invoke(exception, new object[0]);
+            return exception;
+        }
+    }
+}
\ No newline at end of file
product/infrastructure/proxies/Interceptor.cs
@@ -0,0 +1,7 @@
+namespace infrastructure.proxies
+{
+    public interface Interceptor
+    {
+        void intercept(Invocation invocation);
+    }
+}
\ No newline at end of file
product/infrastructure/proxies/Invocation.cs
@@ -0,0 +1,12 @@
+using System.Reflection;
+
+namespace infrastructure.proxies
+{
+    public interface Invocation
+    {
+        void proceed();
+        object[] arguments { get; }
+        MethodInfo method { get; }
+        object return_value { get; set; }
+    }
+}
\ No newline at end of file
product/infrastructure/proxies/MethodCallInvocation.cs
@@ -0,0 +1,47 @@
+using System.Collections.Generic;
+using System.Reflection;
+using System.Runtime.Remoting.Messaging;
+using utility;
+
+namespace infrastructure.proxies
+{
+    public class MethodCallInvocation<T> : Invocation
+    {
+        readonly IMethodCallMessage call;
+        readonly T target;
+        readonly Stack<Interceptor> interceptors;
+
+        public MethodCallInvocation(IEnumerable<Interceptor> interceptors, IMethodCallMessage call, T target)
+        {
+            this.call = call;
+            this.target = target;
+            this.interceptors = new Stack<Interceptor>(interceptors);
+            arguments = call.Properties["__Args"].downcast_to<object[]>();
+            method = call.MethodBase.downcast_to<MethodInfo>();
+        }
+
+        public object[] arguments { get; set; }
+
+        public MethodInfo method { get; set; }
+
+        public object return_value { get; set; }
+
+        public void proceed()
+        {
+            if (interceptors.Count > 0)
+            {
+                interceptors.Pop().intercept(this);
+                return;
+            }
+
+            try
+            {
+                return_value = call.MethodBase.Invoke(target, arguments);
+            }
+            catch (TargetInvocationException e)
+            {
+                throw e.InnerException.preserve_stack_trace();
+            }
+        }
+    }
+}
\ No newline at end of file
product/infrastructure/proxies/ProxyFactory.cs
@@ -0,0 +1,10 @@
+namespace infrastructure.proxies
+{
+    static public class ProxyFactory
+    {
+        static public T create<T>(T target, params Interceptor[] interceptors)
+        {
+            return new RemotingProxyFactory<T>(target, interceptors).create_proxy();
+        }
+    }
+}
\ No newline at end of file
product/infrastructure/proxies/RemotingProxyFactory.cs
@@ -0,0 +1,44 @@
+using System.Collections.Generic;
+using System.Runtime.Remoting.Messaging;
+using System.Runtime.Remoting.Proxies;
+using utility;
+
+namespace infrastructure.proxies
+{
+    public class RemotingProxyFactory<T> : RealProxy
+    {
+        readonly T target;
+        readonly IEnumerable<Interceptor> interceptors;
+
+        public RemotingProxyFactory(T target, IEnumerable<Interceptor> interceptors) : base(typeof (T))
+        {
+            this.target = target;
+            this.interceptors = interceptors;
+        }
+
+        public override IMessage Invoke(IMessage message)
+        {
+            if (message.is_an_implementation_of<IMethodCallMessage>())
+            {
+                var call = message.downcast_to<IMethodCallMessage>();
+                var invocation = new MethodCallInvocation<T>(interceptors, call, target);
+                invocation.proceed();
+                return return_value(invocation.return_value, invocation.arguments, call);
+            }
+            return null;
+        }
+
+        IMessage return_value(object return_value, object[] out_parameters, IMethodCallMessage call)
+        {
+            return new ReturnMessage(return_value,
+                                     out_parameters,
+                                     out_parameters == null ? 0 : out_parameters.Length,
+                                     call.LogicalCallContext, call);
+        }
+
+        public T create_proxy()
+        {
+            return GetTransparentProxy().downcast_to<T>();
+        }
+    }
+}
\ No newline at end of file
product/infrastructure/reflection/ApplicationAssembly.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using utility;
+
+namespace infrastructure.reflection
+{
+    public class ApplicationAssembly : Assembly
+    {
+        IList<Type> types = new List<Type>();
+
+        public ApplicationAssembly(params System.Reflection.Assembly[] assemblies)
+        {
+            assemblies.each(x => types.add_range(x.GetTypes()));
+        }
+
+        public IEnumerable<Type> all_types()
+        {
+            return types;
+        }
+
+        public IEnumerable<Type> all_types(Specification<Type> matching)
+        {
+            return all_types().where(x => matching.is_satisfied_by(x));
+        }
+
+        public IEnumerable<Type> all_classes_that_implement<Contract>()
+        {
+            return all_types()
+                .where(x => typeof (Contract).IsAssignableFrom(x))
+                .where(x => !x.IsInterface)
+                .where(x => !x.IsAbstract)
+                .where(x => !x.IsGenericType);
+        }
+    }
+}
\ No newline at end of file
product/infrastructure/reflection/Assembly.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using utility;
+
+namespace infrastructure.reflection
+{
+    public interface Assembly
+    {
+        IEnumerable<Type> all_types();
+        IEnumerable<Type> all_types(Specification<Type> matching);
+        IEnumerable<Type> all_classes_that_implement<T>();
+    }
+}
\ No newline at end of file
product/infrastructure/reflection/EnvironmentExtensions.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace infrastructure.reflection
+{
+    public static class EnvironmentExtensions
+    {
+        public static string startup_directory<T>(this T item)
+        {
+            return AppDomain.CurrentDomain.BaseDirectory;
+        }
+    }
+}
\ No newline at end of file
product/infrastructure/registries/DefaultRegistry.cs
@@ -0,0 +1,32 @@
+using System.Collections;
+using System.Collections.Generic;
+using infrastructure.container;
+using utility;
+
+namespace infrastructure.registries
+{
+    public class DefaultRegistry<T> : Registry<T>
+    {
+        readonly DependencyRegistry registry;
+
+        public DefaultRegistry(DependencyRegistry registry)
+        {
+            this.registry = registry;
+        }
+
+        public IEnumerable<T> all()
+        {
+            return registry.get_all<T>();
+        }
+
+        public IEnumerator<T> GetEnumerator()
+        {
+            return all().GetEnumerator();
+        }
+
+        IEnumerator IEnumerable.GetEnumerator()
+        {
+            return GetEnumerator();
+        }
+    }
+}
\ No newline at end of file
product/infrastructure/threading/AsynchronousCommandProcessor.cs
@@ -0,0 +1,113 @@
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using infrastructure.logging;
+using utility;
+
+namespace infrastructure.threading
+{
+    public class AsynchronousCommandProcessor : CommandProcessor
+    {
+        readonly Queue<Command> queued_commands;
+        readonly EventWaitHandle manual_reset;
+        readonly IList<Thread> worker_threads;
+        bool keep_working;
+
+        static public readonly Command Empty = new EmptyCommand();
+
+        public AsynchronousCommandProcessor()
+        {
+            queued_commands = new Queue<Command>();
+            worker_threads = new List<Thread>();
+            manual_reset = new ManualResetEvent(false);
+        }
+
+        public void add(Action command)
+        {
+            add(new AnonymousCommand(command));
+        }
+
+        public void add(Command 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()
+        {
+            var command = Empty;
+            within_lock(() =>
+                        {
+                            if (queued_commands.Count == 0)
+                                manual_reset.Reset();
+                            else
+                                command = queued_commands.Dequeue();
+                        });
+            safely_invoke(() =>
+                          {
+                              command.run();
+                          });
+            reset_thread();
+        }
+
+        void safely_invoke(Action action)
+        {
+            try
+            {
+                action();
+            }
+            catch (Exception e)
+            {
+                this.log().error(e);
+            }
+        }
+
+        void reset_thread()
+        {
+            within_lock(() =>
+                        {
+                            if (queued_commands.Count > 0) manual_reset.Set();
+                            else manual_reset.Reset();
+                        });
+        }
+
+        void within_lock(Action action)
+        {
+            lock (queued_commands)
+            {
+                action();
+            }
+        }
+    }
+}
\ No newline at end of file
product/infrastructure/threading/BackgroundThread.cs
@@ -0,0 +1,30 @@
+using utility;
+
+namespace infrastructure.threading
+{
+    public interface IBackgroundThread : DisposableCommand {}
+
+    public class BackgroundThread : IBackgroundThread
+    {
+        readonly IWorkerThread worker_thread;
+
+        public BackgroundThread(DisposableCommand command_to_execute) : this(command_to_execute, new WorkerThread()) {}
+
+        public BackgroundThread(DisposableCommand 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/infrastructure/threading/BackgroundThreadFactory.cs
@@ -0,0 +1,49 @@
+using System;
+using infrastructure.container;
+using utility;
+
+namespace infrastructure.threading
+{
+    public interface IBackgroundThreadFactory
+    {
+        IBackgroundThread create_for<CommandToExecute>() where CommandToExecute : DisposableCommand;
+        IBackgroundThread create_for(Action action);
+    }
+
+    public class BackgroundThreadFactory : IBackgroundThreadFactory
+    {
+        readonly DependencyRegistry registry;
+
+        public BackgroundThreadFactory(DependencyRegistry registry)
+        {
+            this.registry = registry;
+        }
+
+        public IBackgroundThread create_for<CommandToExecute>() where CommandToExecute : DisposableCommand
+        {
+            return new BackgroundThread(registry.get_a<CommandToExecute>());
+        }
+
+        public IBackgroundThread create_for(Action action)
+        {
+            return new BackgroundThread(new AnonymousDisposableCommand(action));
+        }
+
+        class AnonymousDisposableCommand : DisposableCommand
+        {
+            readonly Action action;
+
+            public AnonymousDisposableCommand(Action action)
+            {
+                this.action = action;
+            }
+
+            public void run()
+            {
+                action();
+            }
+
+            public void Dispose() {}
+        }
+    }
+}
\ No newline at end of file
product/infrastructure/threading/CommandProcessor.cs
@@ -0,0 +1,12 @@
+using System;
+using utility;
+
+namespace infrastructure.threading
+{
+    public interface CommandProcessor : Command
+    {
+        void add(Action command);
+        void add(Command command_to_process);
+        void stop();
+    }
+}
\ No newline at end of file
product/infrastructure/threading/CurrentThread.cs
@@ -0,0 +1,19 @@
+using System.Threading;
+
+namespace infrastructure.threading
+{
+    public class CurrentThread : IThread
+    {
+        public T provide_slot_for<T>() where T : class, new()
+        {
+            var slot = Thread.GetNamedDataSlot(create_key_for<T>());
+            if (null == Thread.GetData(slot)) Thread.SetData(slot, new T());
+            return (T) Thread.GetData(slot);
+        }
+
+        string create_key_for<T>()
+        {
+            return Thread.CurrentThread.ManagedThreadId + GetType().FullName + typeof (T).FullName;
+        }
+    }
+}
\ No newline at end of file
product/infrastructure/threading/IntervalTimer.cs
@@ -0,0 +1,48 @@
+using System;
+using System.Collections.Generic;
+using System.Timers;
+
+namespace 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/infrastructure/threading/IThread.cs
@@ -0,0 +1,7 @@
+namespace infrastructure.threading
+{
+    public interface IThread
+    {
+        T provide_slot_for<T>() where T : class, new();
+    }
+}
\ No newline at end of file
product/infrastructure/threading/ITimerClient.cs
@@ -0,0 +1,7 @@
+namespace infrastructure.threading
+{
+    public interface ITimerClient
+    {
+        void notify();
+    }
+}
\ No newline at end of file
product/infrastructure/threading/IWorkerThread.cs
@@ -0,0 +1,12 @@
+using System;
+using System.ComponentModel;
+
+namespace infrastructure.threading
+{
+    public interface IWorkerThread : IDisposable
+    {
+        event DoWorkEventHandler DoWork;
+        event EventHandler Disposed;
+        void begin();
+    }
+}
\ No newline at end of file
product/infrastructure/threading/PerThread.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Threading;
+using utility;
+
+namespace infrastructure.threading
+{
+    public class PerThread : IContext
+    {
+        readonly IDictionary<int, LocalDataStoreSlot> slots;
+        readonly object mutex = new object();
+
+        public PerThread()
+        {
+            slots = new Dictionary<int, LocalDataStoreSlot>();
+        }
+
+        public bool contains<T>(IKey<T> key)
+        {
+            return key.is_found_in(get_items());
+        }
+
+        public void add<T>(IKey<T> key, T value)
+        {
+            key.add_value_to(get_items(), value);
+        }
+
+        public T value_for<T>(IKey<T> key)
+        {
+            return key.parse_from(get_items());
+        }
+
+        public void remove<T>(IKey<T> key)
+        {
+            key.remove_from(get_items());
+        }
+
+        IDictionary get_items()
+        {
+            var id = Thread.CurrentThread.ManagedThreadId;
+            within_lock(() =>
+            {
+                if (!slots.ContainsKey(id))
+                {
+                    var slot = Thread.GetNamedDataSlot(GetType().FullName);
+                    slots.Add(id, slot);
+                    Thread.SetData(slot, new Hashtable());
+                }
+            });
+            return (IDictionary) Thread.GetData(slots[id]);
+        }
+
+        void within_lock(Action action)
+        {
+            lock (mutex) action();
+        }
+    }
+}
\ No newline at end of file
product/infrastructure/threading/PerThreadScopedStorage.cs
@@ -0,0 +1,20 @@
+using System.Collections;
+using utility;
+
+namespace infrastructure.threading
+{
+    public class PerThreadScopedStorage : IScopedStorage
+    {
+        readonly IThread current_thread;
+
+        public PerThreadScopedStorage(IThread current_thread)
+        {
+            this.current_thread = current_thread;
+        }
+
+        public IDictionary provide_storage()
+        {
+            return current_thread.provide_slot_for<Hashtable>();
+        }
+    }
+}
\ No newline at end of file
product/infrastructure/threading/SynchronizationContextFactory.cs
@@ -0,0 +1,23 @@
+using System.Threading;
+using infrastructure.container;
+using utility;
+
+namespace infrastructure.threading
+{
+    public interface ISynchronizationContextFactory : Factory<ISynchronizationContext> {}
+
+    public class SynchronizationContextFactory : ISynchronizationContextFactory
+    {
+        readonly DependencyRegistry registry;
+
+        public SynchronizationContextFactory(DependencyRegistry registry)
+        {
+            this.registry = registry;
+        }
+
+        public ISynchronizationContext create()
+        {
+            return new SynchronizedContext(registry.get_a<SynchronizationContext>());
+        }
+    }
+}
\ No newline at end of file
product/infrastructure/threading/SynchronizedCommand.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Threading;
+using utility;
+
+namespace infrastructure.threading
+{
+    public interface ISynchronizedCommand : Command<Action>, Command<Command> {}
+
+    public class SynchronizedCommand : ISynchronizedCommand
+    {
+        readonly SynchronizationContext context;
+
+        public SynchronizedCommand(SynchronizationContext context)
+        {
+            this.context = context;
+        }
+
+        public void run_against(Action item)
+        {
+            context.Post(x => item(), new object());
+        }
+
+        public void run_against(Command item)
+        {
+            run_against(item.run);
+        }
+    }
+}
\ No newline at end of file
product/infrastructure/threading/SynchronizedContext.cs
@@ -0,0 +1,23 @@
+using System.Threading;
+using utility;
+
+namespace infrastructure.threading
+{
+    public interface ISynchronizationContext : Command<Command> {}
+
+    public class SynchronizedContext : ISynchronizationContext
+    {
+        readonly SynchronizationContext context;
+
+        public SynchronizedContext(SynchronizationContext context)
+        {
+            this.context = context;
+        }
+
+        public void run_against(Command item)
+        {
+            context.Post(x => item.run(), new object());
+            //context.Send(x => item.run(), new object());
+        }
+    }
+}
\ No newline at end of file
product/infrastructure/threading/SynchronousCommandProcessor.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using utility;
+
+namespace infrastructure.threading
+{
+    public class SynchronousCommandProcessor : CommandProcessor
+    {
+        readonly Queue<Command> queued_commands;
+
+        public SynchronousCommandProcessor()
+        {
+            queued_commands = new Queue<Command>();
+        }
+
+        public void add(Action command)
+        {
+            add(new AnonymousCommand(command));
+        }
+
+        public void add(Command 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/infrastructure/threading/ThreadingExtensions.cs
@@ -0,0 +1,12 @@
+using utility;
+
+namespace infrastructure.threading
+{
+    static public class ThreadingExtensions
+    {
+        static public IBackgroundThread on_a_background_thread(this DisposableCommand command)
+        {
+            return new BackgroundThread(command);
+        }
+    }
+}
\ No newline at end of file
product/infrastructure/threading/TimerFactory.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Timers;
+
+namespace 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/infrastructure/threading/WorkerThread.cs
@@ -0,0 +1,50 @@
+using System;
+using System.ComponentModel;
+using infrastructure.logging;
+
+namespace 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/infrastructure/infrastructure.csproj
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{CC006EB6-4E3C-4497-B8CC-5CAF54E40113}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>infrastructure</RootNamespace>
+    <AssemblyName>infrastructure</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="cloning\BinarySerializer.cs" />
+    <Compile Include="cloning\FileStreamSerializer.cs" />
+    <Compile Include="cloning\Prototype.cs" />
+    <Compile Include="cloning\Serializer.cs" />
+    <Compile Include="container\DependencyRegistry.cs" />
+    <Compile Include="container\DependencyResolutionException.cs" />
+    <Compile Include="container\Resolve.cs" />
+    <Compile Include="debugging\Launch.cs" />
+    <Compile Include="filesystem\ApplicationFile.cs" />
+    <Compile Include="filesystem\File.cs" />
+    <Compile Include="logging\Log.cs" />
+    <Compile Include="logging\LogFactory.cs" />
+    <Compile Include="logging\Loggable.cs" />
+    <Compile Include="logging\Logger.cs" />
+    <Compile Include="logging\LoggingExtensions.cs" />
+    <Compile Include="logging\TextLogger.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="proxies\ExceptionExtensions.cs" />
+    <Compile Include="proxies\Interceptor.cs" />
+    <Compile Include="proxies\Invocation.cs" />
+    <Compile Include="proxies\MethodCallInvocation.cs" />
+    <Compile Include="proxies\ProxyFactory.cs" />
+    <Compile Include="proxies\RemotingProxyFactory.cs" />
+    <Compile Include="reflection\ApplicationAssembly.cs" />
+    <Compile Include="reflection\Assembly.cs" />
+    <Compile Include="reflection\EnvironmentExtensions.cs" />
+    <Compile Include="registries\DefaultRegistry.cs" />
+    <Compile Include="threading\AsynchronousCommandProcessor.cs" />
+    <Compile Include="threading\BackgroundThread.cs" />
+    <Compile Include="threading\BackgroundThreadFactory.cs" />
+    <Compile Include="threading\CommandProcessor.cs" />
+    <Compile Include="threading\CurrentThread.cs" />
+    <Compile Include="threading\IntervalTimer.cs" />
+    <Compile Include="threading\IThread.cs" />
+    <Compile Include="threading\ITimerClient.cs" />
+    <Compile Include="threading\IWorkerThread.cs" />
+    <Compile Include="threading\PerThread.cs" />
+    <Compile Include="threading\PerThreadScopedStorage.cs" />
+    <Compile Include="threading\SynchronizationContextFactory.cs" />
+    <Compile Include="threading\SynchronizedCommand.cs" />
+    <Compile Include="threading\SynchronizedContext.cs" />
+    <Compile Include="threading\SynchronousCommandProcessor.cs" />
+    <Compile Include="threading\ThreadingExtensions.cs" />
+    <Compile Include="threading\TimerFactory.cs" />
+    <Compile Include="threading\WorkerThread.cs">
+      <SubType>Component</SubType>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\utility\utility.csproj">
+      <Project>{39B95E47-DA9C-4C80-A395-515600C55D4B}</Project>
+      <Name>utility</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. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file
product/specs/ApplicationControllerSpecs.cs
@@ -1,39 +0,0 @@
-using desktop.ui;
-using Machine.Specifications;
-
-namespace specs
-{
-    public class ApplicationControllerSpecs
-    {
-        public class concern
-        {
-            Establish context = () =>
-            {
-                start_all_modules = The.dependency<IStartAllModules>();
-                event_aggregator = The.dependency<EventAggregator>();
-                region_manager = The.dependency<IRegionManager>();
-                sut = new WPFApplicationController(start_all_modules, event_aggregator, region_manager);
-            };
-
-            protected static WPFApplicationController sut;
-            protected static IStartAllModules start_all_modules;
-            protected static EventAggregator event_aggregator;
-            protected static IRegionManager region_manager;
-        }
-
-        public class when_starting_up : concern
-        {
-            Because of = () => { sut.start(); };
-
-            It should_start_all_of_the_application_modules = () =>
-            {
-                start_all_modules.received(x => x.run(region_manager));
-            };
-
-            It should_register_itself_as_a_listener_with_the_event_aggregator = () =>
-            {
-                event_aggregator.received(x => x.register(sut));
-            };
-        }
-    }
-}
\ No newline at end of file
product/specs/specs.csproj
@@ -50,7 +50,6 @@
     <Reference Include="WindowsBase" />
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="ApplicationControllerSpecs.cs" />
     <Compile Include="Mocking.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="The.cs" />
product/utility/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("utility")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("utility")]
+[assembly: AssemblyCopyright("Copyright ©  2011")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("fcb24300-de08-47a5-a4b0-efb606c1a008")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
product/utility/AndSpecification.cs
@@ -0,0 +1,19 @@
+namespace utility
+{
+    public class AndSpecification<T> : Specification<T>
+    {
+        readonly Specification<T> left;
+        readonly Specification<T> right;
+
+        public AndSpecification(Specification<T> left, Specification<T> right)
+        {
+            this.left = left;
+            this.right = right;
+        }
+
+        public bool is_satisfied_by(T item)
+        {
+            return left.is_satisfied_by(item) && right.is_satisfied_by(item);
+        }
+    }
+}
\ No newline at end of file
product/utility/AnonymousCommand.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Linq.Expressions;
+
+namespace utility
+{
+    public class AnonymousCommand : Command
+    {
+        readonly Action action;
+
+        public AnonymousCommand(Expression<Action> action) : this(action.Compile()) {}
+
+        public AnonymousCommand(Action action)
+        {
+            this.action = action;
+        }
+
+        public void run()
+        {
+            action();
+        }
+    }
+}
\ No newline at end of file
product/utility/AnonymousDisposable.cs
@@ -0,0 +1,19 @@
+using System;
+
+namespace utility
+{
+    public class AnonymousDisposable : IDisposable
+    {
+        readonly Action action;
+
+        public AnonymousDisposable(Action action)
+        {
+            this.action = action;
+        }
+
+        public void Dispose()
+        {
+            action();
+        }
+    }
+}
\ No newline at end of file
product/utility/AnonymousMapper.cs
@@ -0,0 +1,19 @@
+using System;
+
+namespace utility
+{
+    public class AnonymousMapper<Input, Output> : Mapper<Input, Output>
+    {
+        readonly Converter<Input, Output> converter;
+
+        public AnonymousMapper(Converter<Input, Output> converter)
+        {
+            this.converter = converter;
+        }
+
+        public Output map_from(Input item)
+        {
+            return converter(item);
+        }
+    }
+}
\ No newline at end of file
product/utility/AttributeExtensions.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Reflection;
+
+namespace utility
+{
+    static public class AttributeExtensions
+    {
+        static public bool is_decorated_with<T>(this object item) where T : Attribute
+        {
+            return item.GetType().is_decorated_with<T>();
+        }
+
+        static public bool is_decorated_with<T>(this ICustomAttributeProvider item) where T : Attribute
+        {
+            return item.IsDefined(typeof (T), true);
+        }
+
+        static public T attribute<T>(this object item) where T : Attribute
+        {
+            return item.GetType().attribute<T>();
+        }
+
+        static public T attribute<T>(this ICustomAttributeProvider item) where T : Attribute
+        {
+            return (T) item.GetCustomAttributes(typeof (T), true)[0];
+        }
+    }
+}
\ No newline at end of file
product/utility/Builder.cs
@@ -0,0 +1,7 @@
+namespace utility
+{
+    public interface Builder<T>
+    {
+        T build();
+    }
+}
\ No newline at end of file
product/utility/Callback.cs
@@ -0,0 +1,10 @@
+namespace utility
+{
+    public interface Callback : Command
+    {
+    }
+
+    public interface Callback<T> : Command<T>
+    {
+    }
+}
\ No newline at end of file
product/utility/CallbackCommand.cs
@@ -0,0 +1,6 @@
+namespace utility
+{
+    public interface CallbackCommand<T> : Command<Callback<T>>
+    {
+    }
+}
\ No newline at end of file
product/utility/ChainedCommand.cs
@@ -0,0 +1,20 @@
+namespace utility
+{
+    public class ChainedCommand : Command
+    {
+        readonly Command left;
+        readonly Command right;
+
+        public ChainedCommand(Command left, Command right)
+        {
+            this.left = left;
+            this.right = right;
+        }
+
+        public void run()
+        {
+            left.run();
+            right.run();
+        }
+    }
+}
\ No newline at end of file
product/utility/ChainedConfiguration.cs
@@ -0,0 +1,20 @@
+namespace utility
+{
+    public class ChainedConfiguration<T> : Configuration<T>
+    {
+        readonly Configuration<T> first;
+        readonly Configuration<T> second;
+
+        public ChainedConfiguration(Configuration<T> first, Configuration<T> second)
+        {
+            this.first = first;
+            this.second = second;
+        }
+
+        public void configure(T item)
+        {
+            first.configure(item);
+            second.configure(item);
+        }
+    }
+}
\ No newline at end of file
product/utility/ChainedMapper.cs
@@ -0,0 +1,19 @@
+namespace utility
+{
+    public class ChainedMapper<Left, Middle, Right> : Mapper<Left, Right>
+    {
+        readonly Mapper<Left, Middle> left;
+        readonly Mapper<Middle, Right> right;
+
+        public ChainedMapper(Mapper<Left, Middle> left, Mapper<Middle, Right> right)
+        {
+            this.left = left;
+            this.right = right;
+        }
+
+        public Right map_from(Left item)
+        {
+            return right.map_from(left.map_from(item));
+        }
+    }
+}
\ No newline at end of file
product/utility/ChainedParameterizedCommand.cs
@@ -0,0 +1,20 @@
+namespace utility
+{
+    public class ChainedCommand<T> : Command<T>
+    {
+        Command<T> left;
+        Command<T> right;
+
+        public ChainedCommand(Command<T> left, Command<T> right)
+        {
+            this.left = left;
+            this.right = right;
+        }
+
+        public void run_against(T item)
+        {
+            left.run_against(item);
+            right.run_against(item);
+        }
+    }
+}
\ No newline at end of file
product/utility/Clock.cs
@@ -0,0 +1,36 @@
+using System;
+
+namespace utility
+{
+    public static class Clock
+    {
+        private static Func<DateTime> time_provider;
+
+        static Clock()
+        {
+            reset();
+        }
+
+        public static Date today()
+        {
+            return time_provider();
+        }
+
+        public static DateTime now()
+        {
+            return time_provider();
+        }
+
+#if DEBUG
+        public static void change_time_provider_to(Func<DateTime> new_time_provider)
+        {
+            if (new_time_provider != null) time_provider = new_time_provider;
+        }
+#endif
+
+        public static void reset()
+        {
+            time_provider = () => DateTime.Now;
+        }
+    }
+}
\ No newline at end of file
product/utility/Command.cs
@@ -0,0 +1,12 @@
+namespace utility
+{
+    public interface Command
+    {
+        void run();
+    }
+
+    public interface Command<T>
+    {
+        void run_against(T item);
+    }
+}
\ No newline at end of file
product/utility/CommandExtensions.cs
@@ -0,0 +1,27 @@
+using System;
+
+namespace utility
+{
+    static public class CommandExtensions
+    {
+        static public utility.Command then<Command>(this utility.Command left) where Command : utility.Command, new()
+        {
+            return then(left, new Command());
+        }
+
+        static public Command then(this Command left, Command right)
+        {
+            return new ChainedCommand(left, right);
+        }
+
+        static public Command then(this Command left, Action right)
+        {
+            return new ChainedCommand(left, new AnonymousCommand(right));
+        }
+
+        static public Command<T> then<T>(this Command<T> left, Command<T> right)
+        {
+            return new ChainedCommand<T>(left, right);
+        }
+    }
+}
\ No newline at end of file
product/utility/ComparableExtensions.cs
@@ -0,0 +1,17 @@
+using System;
+
+namespace utility
+{
+    static public class ComparableExtensions
+    {
+        static public bool is_before<T>(this T left, T right) where T : IComparable<T>
+        {
+            return left.CompareTo(right) < 0;
+        }
+
+        static public bool is_after<T>(this T left, T right) where T : IComparable<T>
+        {
+            return left.CompareTo(right) > 0;
+        }
+    }
+}
\ No newline at end of file
product/utility/ComponentFactory.cs
@@ -0,0 +1,4 @@
+namespace utility
+{
+    public interface ComponentFactory<T> : Factory<T> where T : new() {}
+}
\ No newline at end of file
product/utility/Configuration.cs
@@ -0,0 +1,7 @@
+namespace utility
+{
+    public interface Configuration<T>
+    {
+        void configure(T item);
+    }
+}
\ No newline at end of file
product/utility/ConfigurationExtensions.cs
@@ -0,0 +1,16 @@
+namespace utility
+{
+    static public class ConfigurationExtensions
+    {
+        static public Configuration<T> then<T>(this Configuration<T> first, Configuration<T> second)
+        {
+            return new ChainedConfiguration<T>(first, second);
+        }
+
+        static public T and_configure_with<T>(this T item, Configuration<T> configuration)
+        {
+            configuration.configure(item);
+            return item;
+        }
+    }
+}
\ No newline at end of file
product/utility/Context.cs
@@ -0,0 +1,34 @@
+using System.Collections;
+
+namespace utility
+{
+    public class Context : IContext
+    {
+        readonly IDictionary items;
+
+        public Context(IDictionary items)
+        {
+            this.items = items;
+        }
+
+        public bool contains<T>(IKey<T> key)
+        {
+            return key.is_found_in(items);
+        }
+
+        public void add<T>(IKey<T> key, T value)
+        {
+            key.add_value_to(items, value);
+        }
+
+        public T value_for<T>(IKey<T> key)
+        {
+            return key.parse_from(items);
+        }
+
+        public void remove<T>(IKey<T> key)
+        {
+            key.remove_from(items);
+        }
+    }
+}
\ No newline at end of file
product/utility/ContextFactory.cs
@@ -0,0 +1,10 @@
+namespace utility
+{
+    public class ContextFactory : IContextFactory
+    {
+        public IContext create_for(IScopedStorage storage)
+        {
+            return new Context(storage.provide_storage());
+        }
+    }
+}
\ No newline at end of file
product/desktop.ui/ConversionExtensions.cs → product/utility/ConversionExtensions.cs
@@ -1,7 +1,7 @@
-using System;
+using System;
 using System.Collections;
 
-namespace desktop.ui
+namespace utility
 {
     public static class ConversionExtensions
     {
product/utility/Date.cs
@@ -0,0 +1,85 @@
+using System;
+using System.Globalization;
+
+namespace utility
+{
+    [Serializable]
+    public class Date :  IComparable<Date>, IComparable, IEquatable<Date>
+    {
+        readonly long ticks;
+        static public readonly Date First = new Date(DateTime.MinValue);
+        static public readonly Date Last = new Date(DateTime.MaxValue);
+
+        public Date( DateTime date)
+        {
+            this.ticks = date.Date.Ticks;
+        }
+
+        public DateTime to_date_time()
+        {
+            return new DateTime(ticks);
+        }
+
+        static public implicit operator Date(DateTime date)
+        {
+            return new Date(date);
+        }
+
+        static public implicit operator DateTime(Date date)
+        {
+            return date.to_date_time();
+        }
+
+        public int CompareTo(Date other)
+        {
+            var the_other_date = other.downcast_to<Date>();
+            if (ticks.Equals(the_other_date.ticks))
+            {
+                return 0;
+            }
+            return ticks > the_other_date.ticks ? 1 : -1;
+        }
+
+        public bool Equals(Date other)
+        {
+            if (ReferenceEquals(null, other)) return false;
+            if (ReferenceEquals(this, other)) return true;
+            return other.ticks == ticks;
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != typeof (Date)) return false;
+            return Equals((Date) obj);
+        }
+
+        public override int GetHashCode()
+        {
+            return ticks.GetHashCode();
+        }
+
+        public static bool operator ==(Date left, Date right)
+        {
+            return Equals(left, right);
+        }
+
+        public static bool operator !=(Date left, Date right)
+        {
+            return !Equals(left, right);
+        }
+
+        public override string ToString()
+        {
+            return new DateTime(ticks, DateTimeKind.Local).ToString("MMM dd yyyy", CultureInfo.InvariantCulture);
+        }
+
+        int IComparable.CompareTo(object obj)
+        {
+            if (obj.is_an_implementation_of<Date>())
+                return CompareTo(obj.downcast_to<Date>());
+            throw new InvalidOperationException();
+        }
+    }
+}
\ No newline at end of file
product/utility/DateExtensions.cs
@@ -0,0 +1,25 @@
+namespace utility
+{
+    static public class DateExtensions
+    {
+        static public Date plus_years(this Date date, int years)
+        {
+            return date.to_date_time().AddYears(years);
+        }
+
+        static public Date plus_days(this Date date, int days)
+        {
+            return date.to_date_time().AddDays(days);
+        }
+
+        static public Date minus_days(this Date date, int days)
+        {
+            return date.to_date_time().AddDays(-days);
+        }
+
+        static public Date add_months(this Date date, int months)
+        {
+            return date.to_date_time().AddMonths(months);
+        }
+    }
+}
\ No newline at end of file
product/utility/DefaultConstructorFactory.cs
@@ -0,0 +1,10 @@
+namespace utility
+{
+    public class DefaultConstructorFactory<T> : ComponentFactory<T> where T : new()
+    {
+        public T create()
+        {
+            return new T();
+        }
+    }
+}
\ No newline at end of file
product/utility/DisposableCommand.cs
@@ -0,0 +1,6 @@
+using System;
+
+namespace utility
+{
+    public interface DisposableCommand : Command, IDisposable {}
+}
\ No newline at end of file
product/utility/EmptyCallback.cs
@@ -0,0 +1,9 @@
+namespace utility
+{
+    public class EmptyCallback<T> : Callback<T>, Callback
+    {
+        public void run_against(T item) {}
+
+        public void run() {}
+    }
+}
\ No newline at end of file
product/utility/EmptyCommand.cs
@@ -0,0 +1,9 @@
+namespace utility
+{
+    public class EmptyCommand : Command
+    {
+        public void run()
+        {
+        }
+    }
+}
\ No newline at end of file
product/desktop.ui/Iterating.cs → product/utility/EnumerableExtensions.cs
@@ -1,11 +1,21 @@
-using System;
+using System;
 using System.Collections.Generic;
 using System.Linq;
 
-namespace desktop.ui
+namespace utility
 {
-    static public class Iterating
+    static public class EnumerableExtensions
     {
+        static public IEnumerable<T> where<T>(this IEnumerable<T> items, Func<T, bool> condition_is_met)
+        {
+            return null == items ? Enumerable.Empty<T>() : items.Where(condition_is_met);
+        }
+
+        static public IList<T> databind<T>(this IEnumerable<T> items_to_bind_to)
+        {
+            return null == items_to_bind_to ? new List<T>() : items_to_bind_to.ToList();
+        }
+
         static public IEnumerable<T> sorted_using<T>(this IEnumerable<T> items_to_sort, IComparer<T> sorting_algorithm)
         {
             var sorted_items = new List<T>(items_to_sort);
product/utility/ExpressionExtensions.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Linq.Expressions;
+using System.Reflection;
+
+namespace utility
+{
+    static public class ExpressionExtensions
+    {
+        static public PropertyInfo pick_property<T>(this Expression<Func<T, object>> expression)
+        {
+            return (PropertyInfo) member_expression(expression).Member;
+        }
+
+        static MemberExpression member_expression<T>(Expression<Func<T, object>> expression)
+        {
+            if (expression.Body.NodeType == ExpressionType.Convert)
+                return ((UnaryExpression) expression.Body).Operand as MemberExpression;
+            if (expression.Body.NodeType == ExpressionType.MemberAccess)
+                return expression.Body as MemberExpression;
+            throw new NotImplementedException();
+        }
+    }
+}
\ No newline at end of file
product/utility/Factory.cs
@@ -0,0 +1,7 @@
+namespace utility
+{
+    public interface Factory<T>
+    {
+        T create();
+    }
+}
\ No newline at end of file
product/utility/FactoryDelegate.cs
@@ -0,0 +1,6 @@
+namespace utility
+{
+    public delegate Out FactoryDelegate<In, Out>(In input);
+
+    public delegate Out FactoryDelegate<Out>();
+}
\ No newline at end of file
product/utility/FilteredVisitor.cs
@@ -0,0 +1,19 @@
+namespace utility
+{
+    public class FilteredVisitor<T> : Visitor<T>
+    {
+        readonly Specification<T> condition;
+        readonly Visitor<T> visitor;
+
+        public FilteredVisitor(Specification<T> condition, Visitor<T> visitor)
+        {
+            this.condition = condition;
+            this.visitor = visitor;
+        }
+
+        public void visit(T item_to_visit)
+        {
+            if (condition.is_satisfied_by(item_to_visit)) visitor.visit(item_to_visit);
+        }
+    }
+}
\ No newline at end of file
product/utility/FuncExtensions.cs
@@ -0,0 +1,28 @@
+using System;
+
+namespace utility
+{
+    static public class FuncExtensions
+    {
+        static public readonly object mutex = new object();
+
+        static public Func<T> memorize<T>(this Func<T> item) where T : class
+        {
+            T the_implementation = null;
+            return () =>
+            {
+                if (null == the_implementation)
+                {
+                    lock (mutex)
+                    {
+                        if (null == the_implementation)
+                        {
+                            the_implementation = item();
+                        }
+                    }
+                }
+                return the_implementation;
+            };
+        }
+    }
+}
\ No newline at end of file
product/utility/FuncSpecification.cs
@@ -0,0 +1,19 @@
+using System;
+
+namespace utility
+{
+    public class FuncSpecification<T> : Specification<T>
+    {
+        Func<T, bool> condition;
+
+        public FuncSpecification(Func<T, bool> condition)
+        {
+            this.condition = condition;
+        }
+
+        public bool is_satisfied_by(T item)
+        {
+            return condition(item);
+        }
+    }
+}
\ No newline at end of file
product/utility/IContext.cs
@@ -0,0 +1,10 @@
+namespace utility
+{
+    public interface IContext
+    {
+        bool contains<T>(IKey<T> key);
+        void add<T>(IKey<T> key, T value);
+        T value_for<T>(IKey<T> key);
+        void remove<T>(IKey<T> key);
+    }
+}
\ No newline at end of file
product/utility/IContextFactory.cs
@@ -0,0 +1,7 @@
+namespace utility
+{
+    public interface IContextFactory
+    {
+        IContext create_for(IScopedStorage storage);
+    }
+}
\ No newline at end of file
product/utility/Id.cs
@@ -0,0 +1,46 @@
+using System;
+
+namespace utility
+{
+    [Serializable]
+    public class Id<T>
+    {
+        static public readonly Id<T> Default = new Id<T>(default(T));
+        public T id { get; private set; }
+
+        public Id(T id)
+        {
+            this.id = id;
+        }
+
+        static public implicit operator Id<T>(T id)
+        {
+            return new Id<T>(id);
+        }
+
+        static public implicit operator T(Id<T> id)
+        {
+            return id.id;
+        }
+
+        public bool Equals(Id<T> other)
+        {
+            if (ReferenceEquals(null, other)) return false;
+            if (ReferenceEquals(this, other)) return true;
+            return Equals(other.id, id);
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != typeof (Id<T>)) return false;
+            return Equals((Id<T>) obj);
+        }
+
+        public override int GetHashCode()
+        {
+            return id.GetHashCode();
+        }
+    }
+}
\ No newline at end of file
product/utility/Identifiable.cs
@@ -0,0 +1,7 @@
+namespace utility
+{
+    public interface Identifiable<T>
+    {
+        Id<T> id { get; }
+    }
+}
\ No newline at end of file
product/utility/IKey.cs
@@ -0,0 +1,12 @@
+using System.Collections;
+
+namespace utility
+{
+    public interface IKey<T>
+    {
+        bool is_found_in(IDictionary items);
+        T parse_from(IDictionary items);
+        void remove_from(IDictionary items);
+        void add_value_to(IDictionary items, T value);
+    }
+}
\ No newline at end of file
product/utility/Import.cs
@@ -0,0 +1,7 @@
+namespace utility
+{
+    public interface Import<T>
+    {
+        void import(T item);
+    }
+}
\ No newline at end of file
product/utility/IScopedStorage.cs
@@ -0,0 +1,9 @@
+using System.Collections;
+
+namespace utility
+{
+    public interface IScopedStorage
+    {
+        IDictionary provide_storage();
+    }
+}
\ No newline at end of file
product/utility/ListExtensions.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace utility
+{
+    static public class ListExtensions
+    {
+        static public IListConstraint<T> add<T>(this ICollection<T> items, T item)
+        {
+            return new ListConstraint<T>(items, item);
+        }
+
+        static public IListConstraint<T> add_range<T>(this ICollection<T> items, IEnumerable<T> item)
+        {
+            return new ListConstraint<T>(items, item.ToArray());
+        }
+    }
+
+    public class ListConstraint<T> : IListConstraint<T>
+    {
+        readonly ICollection<T> items;
+        readonly T[] items_to_add;
+
+        public ListConstraint(ICollection<T> list_to_constrain, params T[] items_to_add)
+        {
+            items = list_to_constrain;
+            this.items_to_add = items_to_add;
+            items_to_add.each(list_to_constrain.Add);
+        }
+
+        public void unless(Func<T, bool> predicate)
+        {
+            items_to_add.where(predicate).each(x => items.Remove(x));
+        }
+    }
+
+    public interface IListConstraint<T>
+    {
+        void unless(Func<T, bool> predicate);
+    }
+}
\ No newline at end of file
product/utility/Mapper.cs
@@ -0,0 +1,12 @@
+namespace utility
+{
+    public interface Mapper<Input, Output>
+    {
+        Output map_from(Input item);
+    }
+
+    public interface Mapper
+    {
+        Output map_from<Input, Output>(Input item);
+    }
+}
\ No newline at end of file
product/utility/MappingExtensions.cs
@@ -0,0 +1,48 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace utility
+{
+    static public class MappingExtensions
+    {
+        static public Output map_using<Input, Output>(this Input item, Converter<Input, Output> conversion)
+        {
+            return conversion(item);
+        }
+
+        static public Output map_using<Input, Output>(this Input item, Mapper<Input, Output> mapper)
+        {
+            return map_using(item, x => mapper.map_from(x));
+        }
+
+        static public Output map_using<Input, Output>(this Input item, Mapper mapper)
+        {
+            return map_using(item, x => mapper.map_from<Input, Output>(x));
+        }
+
+        static public IEnumerable<Output> map_all_using<Input, Output>(this IEnumerable<Input> items,
+                                                                       Converter<Input, Output> mapper)
+        {
+            return null == items ? new List<Output>() : items.Select(x => mapper(x));
+        }
+
+        static public IEnumerable<Output> map_all_using<Input, Output>(this IEnumerable<Input> items,
+                                                                       Mapper<Input, Output> mapper)
+        {
+            return map_all_using(items, x => mapper.map_from(x));
+        }
+
+        static public IEnumerable<Output> map_all_using<Input, Output>(this IEnumerable<Input> items,
+                                                                       Mapper mapper)
+        {
+            return map_all_using(items, x => mapper.map_from<Input, Output>(x));
+        }
+
+        static public Mapper<Left, Right> then<Left, Middle, Right>(this Mapper<Left, Middle> left,
+                                                                    Mapper<Middle, Right> right)
+        {
+            return new ChainedMapper<Left, Middle, Right>(left, right);
+        }
+    }
+}
\ No newline at end of file
product/utility/Notification.cs
@@ -0,0 +1,7 @@
+namespace utility
+{
+    public interface Notification
+    {
+        void notify(params NotificationMessage[] messages);
+    }
+}
\ No newline at end of file
product/utility/NotificationMessage.cs
@@ -0,0 +1,42 @@
+namespace utility
+{
+    public class NotificationMessage
+    {
+        public virtual string message { get; set; }
+
+        static public implicit operator string(NotificationMessage message)
+        {
+            return message.ToString();
+        }
+
+        static public implicit operator NotificationMessage(string message)
+        {
+            return new NotificationMessage {message = message};
+        }
+
+        public override string ToString()
+        {
+            return message;
+        }
+
+        public bool Equals(NotificationMessage obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            return Equals(obj.message, message);
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != typeof (NotificationMessage)) return false;
+            return Equals((NotificationMessage) obj);
+        }
+
+        public override int GetHashCode()
+        {
+            return (message != null ? message.GetHashCode() : 0);
+        }
+    }
+}
\ No newline at end of file
product/utility/NotSpecification.cs
@@ -0,0 +1,17 @@
+namespace utility
+{
+    public class NotSpecification<T> : Specification<T>
+    {
+        readonly Specification<T> item_to_match;
+
+        public NotSpecification(Specification<T> item_to_match)
+        {
+            this.item_to_match = item_to_match;
+        }
+
+        public bool is_satisfied_by(T item)
+        {
+            return !item_to_match.is_satisfied_by(item);
+        }
+    }
+}
\ No newline at end of file
product/utility/NumericConversions.cs
@@ -0,0 +1,22 @@
+using System;
+
+namespace utility
+{
+    public static class NumericConversions
+    {
+        public static int to_int<T>(this T item) where T : IConvertible
+        {
+            return Convert.ChangeType(item, typeof (int)).downcast_to<int>();
+        }
+
+        public static long to_long<T>(this T item) where T : IConvertible
+        {
+            return Convert.ChangeType(item, typeof (long)).downcast_to<long>();
+        }
+
+        public static double to_double<T>(this T item) where T : IConvertible
+        {
+            return Convert.ChangeType(item, typeof (double)).downcast_to<double>();
+        }
+    }
+}
\ No newline at end of file
product/utility/Observer.cs
@@ -0,0 +1,4 @@
+namespace utility
+{
+    public delegate void Observer<T>(T item);
+}
\ No newline at end of file
product/utility/OrSpecification.cs
@@ -0,0 +1,19 @@
+namespace utility
+{
+    public class OrSpecification<T> : Specification<T>
+    {
+        readonly Specification<T> left;
+        readonly Specification<T> right;
+
+        public OrSpecification(Specification<T> left, Specification<T> right)
+        {
+            this.left = left;
+            this.right = right;
+        }
+
+        public bool is_satisfied_by(T item)
+        {
+            return left.is_satisfied_by(item) || right.is_satisfied_by(item);
+        }
+    }
+}
\ No newline at end of file
product/utility/Parser.cs
@@ -0,0 +1,7 @@
+namespace utility
+{
+    public interface Parser<T>
+    {
+        T parse();
+    }
+}
\ No newline at end of file
product/utility/Percent.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Globalization;
+
+namespace utility
+{
+    public class Percent
+    {
+        readonly double percentage;
+
+        public Percent(double percentage)
+        {
+            this.percentage = percentage;
+        }
+
+        public Percent(double portion_of_total, double total)
+        {
+            percentage = portion_of_total/total;
+            percentage *= 100;
+            percentage = Math.Round(percentage, 1);
+        }
+
+        public bool represents(Percent other_percent)
+        {
+            return Equals(other_percent);
+        }
+
+        public bool is_less_than(Percent other_percent)
+        {
+            return percentage.CompareTo(other_percent.percentage) < 0;
+        }
+
+        public static implicit operator Percent(double percentage)
+        {
+            return new Percent(percentage);
+        }
+
+        public bool Equals(Percent other)
+        {
+            if (ReferenceEquals(null, other)) return false;
+            if (ReferenceEquals(this, other)) return true;
+            return other.percentage == percentage;
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != typeof (Percent)) return false;
+            return Equals((Percent) obj);
+        }
+
+        public override int GetHashCode()
+        {
+            return percentage.GetHashCode();
+        }
+
+        public override string ToString()
+        {
+            return percentage.ToString(CultureInfo.InvariantCulture);
+        }
+    }
+}
\ No newline at end of file
product/utility/PredicateSpecification.cs
@@ -0,0 +1,19 @@
+using System;
+
+namespace utility
+{
+    public class PredicateSpecification<T> : Specification<T>
+    {
+        readonly Predicate<T> criteria;
+
+        public PredicateSpecification(Predicate<T> criteria)
+        {
+            this.criteria = criteria;
+        }
+
+        public bool is_satisfied_by(T item)
+        {
+            return criteria(item);
+        }
+    }
+}
\ No newline at end of file
product/utility/Query.cs
@@ -0,0 +1,12 @@
+namespace utility
+{
+    public interface Query<TOutput>
+    {
+        TOutput fetch();
+    }
+
+    public interface Query<TInput, TOutput>
+    {
+        TOutput fetch(TInput item);
+    }
+}
\ No newline at end of file
product/utility/Registry.cs
@@ -0,0 +1,9 @@
+using System.Collections.Generic;
+
+namespace utility
+{
+    public interface Registry<T> : IEnumerable<T>
+    {
+        IEnumerable<T> all();
+    }
+}
\ No newline at end of file
product/utility/RegistryExtensions.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace utility
+{
+    public static class RegistryExtensions
+    {
+        public static K find_an_implementation_of<T, K>(this Registry<T> registry) where K : T
+        {
+            try
+            {
+                return registry
+                    .all()
+                    .Single(p => p.is_an_implementation_of<K>())
+                    .downcast_to<K>();
+            }
+            catch (Exception exception)
+            {
+                throw new Exception("Could Not Find an implementation of".format(typeof (K)), exception);
+            }
+        }
+
+        public static IEnumerable<T> sort_all_using<T>(this Registry<T> registry, IComparer<T> comparer)
+        {
+            return registry.all().sorted_using(comparer);
+        }
+    }
+}
\ No newline at end of file
product/utility/SingletonScopedStorage.cs
@@ -0,0 +1,14 @@
+using System.Collections;
+
+namespace utility
+{
+    public class SingletonScopedStorage : IScopedStorage
+    {
+        static readonly IDictionary storage = new Hashtable();
+
+        public IDictionary provide_storage()
+        {
+            return storage;
+        }
+    }
+}
\ No newline at end of file
product/utility/Specification.cs
@@ -0,0 +1,7 @@
+namespace utility
+{
+    public interface Specification<T>
+    {
+        bool is_satisfied_by(T item);
+    }
+}
\ No newline at end of file
product/utility/SpecificationExtensions.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Collections.Generic;
+
+namespace utility
+{
+    static public class SpecificationExtensions
+    {
+        static public IEnumerable<T> that_satisfy<T>(this IEnumerable<T> items_to_peek_in_to,
+                                                     Predicate<T> criteria_to_satisfy)
+        {
+            foreach (var item in items_to_peek_in_to ?? new List<T>())
+                if (item.satisfies(criteria_to_satisfy)) yield return item;
+        }
+
+        static public bool satisfies<T>(this T item_to_interrogate, Predicate<T> criteria_to_satisfy)
+        {
+            return criteria_to_satisfy(item_to_interrogate);
+        }
+
+        static public bool satisfies<T>(this T item_to_validate, Specification<T> criteria_to_satisfy)
+        {
+            return item_to_validate.satisfies(criteria_to_satisfy.is_satisfied_by);
+        }
+
+        static public Specification<T> and<T>(this Specification<T> left, Specification<T> right)
+        {
+            return new PredicateSpecification<T>(x => left.is_satisfied_by(x) && right.is_satisfied_by(x));
+        }
+
+        static public Specification<T> or<T>(this Specification<T> left, Specification<T> right)
+        {
+            return new PredicateSpecification<T>(x => left.is_satisfied_by(x) || right.is_satisfied_by(x));
+        }
+
+        static public Specification<T> not<T>(this Specification<T> original)
+        {
+            return new PredicateSpecification<T>(x => !original.is_satisfied_by(x));
+        }
+    }
+}
\ No newline at end of file
product/utility/State.cs
@@ -0,0 +1,6 @@
+namespace utility
+{
+    public interface State
+    {
+    }
+}
\ No newline at end of file
product/desktop.ui/StringExtensions.cs → product/utility/StringExtensions.cs
@@ -1,4 +1,4 @@
-namespace desktop.ui
+namespace utility
 {
     static public class StringExtensions
     {
product/utility/SubjectOf.cs
@@ -0,0 +1,7 @@
+namespace utility
+{
+    public interface SubjectOf<State> where State : utility.State
+    {
+        void change_state_to(State new_state);
+    }
+}
\ No newline at end of file
product/utility/TypedKey.cs
@@ -0,0 +1,50 @@
+using System.Collections;
+
+namespace utility
+{
+    public class TypedKey<T> : IKey<T>
+    {
+        public bool is_found_in(IDictionary items)
+        {
+            return items.Contains(create_key());
+        }
+
+        public T parse_from(IDictionary items)
+        {
+            return (T) items[create_key()];
+        }
+
+        public void remove_from(IDictionary items)
+        {
+            if (is_found_in(items)) items.Remove(create_key());
+        }
+
+        public void add_value_to(IDictionary items, T value)
+        {
+            items[create_key()] = value;
+        }
+
+        public bool Equals(TypedKey<T> obj)
+        {
+            return !ReferenceEquals(null, obj);
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != typeof (TypedKey<T>)) return false;
+            return Equals((TypedKey<T>) obj);
+        }
+
+        public override int GetHashCode()
+        {
+            return GetType().GetHashCode();
+        }
+
+        string create_key()
+        {
+            return GetType().FullName;
+        }
+    }
+}
\ No newline at end of file
product/utility/TypeExtensions.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Linq;
+using System.Reflection;
+
+namespace utility
+{
+    public static class TypeExtensions
+    {
+        public static Type last_interface(this Type type)
+        {
+            return type.GetInterfaces()[type.GetInterfaces().Length - 1];
+        }
+
+        public static Type first_interface(this Type type)
+        {
+            return type.GetInterfaces()[0];
+        }
+
+        public static bool is_a_generic_type(this Type type)
+        {
+            //return type.IsGenericType;
+            return type.IsGenericTypeDefinition;
+        }
+
+        public static object default_value(this Type type)
+        {
+            return (type.IsValueType ? Activator.CreateInstance(type) : null);
+        }
+
+        public static Attribute get_attribute<Attribute>(this ICustomAttributeProvider provider)
+            where Attribute : System.Attribute
+        {
+            return
+                provider
+                    .GetCustomAttributes(typeof (Attribute), false)
+                    .Select(x => x.downcast_to<Attribute>())
+                    .First();
+        }
+    }
+}
\ No newline at end of file
product/utility/utility.csproj
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{39B95E47-DA9C-4C80-A395-515600C55D4B}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>utility</RootNamespace>
+    <AssemblyName>utility</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="AndSpecification.cs" />
+    <Compile Include="AnonymousCommand.cs" />
+    <Compile Include="AnonymousDisposable.cs" />
+    <Compile Include="AnonymousMapper.cs" />
+    <Compile Include="AttributeExtensions.cs" />
+    <Compile Include="Builder.cs" />
+    <Compile Include="Callback.cs" />
+    <Compile Include="CallbackCommand.cs" />
+    <Compile Include="ChainedCommand.cs" />
+    <Compile Include="ChainedConfiguration.cs" />
+    <Compile Include="ChainedMapper.cs" />
+    <Compile Include="ChainedParameterizedCommand.cs" />
+    <Compile Include="Clock.cs" />
+    <Compile Include="Command.cs" />
+    <Compile Include="CommandExtensions.cs" />
+    <Compile Include="ComparableExtensions.cs" />
+    <Compile Include="ComponentFactory.cs" />
+    <Compile Include="Configuration.cs" />
+    <Compile Include="ConfigurationExtensions.cs" />
+    <Compile Include="Context.cs" />
+    <Compile Include="ContextFactory.cs" />
+    <Compile Include="ConversionExtensions.cs" />
+    <Compile Include="Date.cs" />
+    <Compile Include="DateExtensions.cs" />
+    <Compile Include="DefaultConstructorFactory.cs" />
+    <Compile Include="DisposableCommand.cs" />
+    <Compile Include="EmptyCallback.cs" />
+    <Compile Include="EmptyCommand.cs" />
+    <Compile Include="EnumerableExtensions.cs" />
+    <Compile Include="ExpressionExtensions.cs" />
+    <Compile Include="Factory.cs" />
+    <Compile Include="FactoryDelegate.cs" />
+    <Compile Include="FilteredVisitor.cs" />
+    <Compile Include="FuncExtensions.cs" />
+    <Compile Include="FuncSpecification.cs" />
+    <Compile Include="IContext.cs" />
+    <Compile Include="IContextFactory.cs" />
+    <Compile Include="Id.cs" />
+    <Compile Include="Identifiable.cs" />
+    <Compile Include="IKey.cs" />
+    <Compile Include="Import.cs" />
+    <Compile Include="IScopedStorage.cs" />
+    <Compile Include="ListExtensions.cs" />
+    <Compile Include="Mapper.cs" />
+    <Compile Include="MappingExtensions.cs" />
+    <Compile Include="Notification.cs" />
+    <Compile Include="NotificationMessage.cs" />
+    <Compile Include="NotSpecification.cs" />
+    <Compile Include="NumericConversions.cs" />
+    <Compile Include="Observer.cs" />
+    <Compile Include="OrSpecification.cs" />
+    <Compile Include="Parser.cs" />
+    <Compile Include="Percent.cs" />
+    <Compile Include="PredicateSpecification.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Query.cs" />
+    <Compile Include="Registry.cs" />
+    <Compile Include="RegistryExtensions.cs" />
+    <Compile Include="SingletonScopedStorage.cs" />
+    <Compile Include="Specification.cs" />
+    <Compile Include="SpecificationExtensions.cs" />
+    <Compile Include="State.cs" />
+    <Compile Include="StringExtensions.cs" />
+    <Compile Include="SubjectOf.cs" />
+    <Compile Include="TypedKey.cs" />
+    <Compile Include="TypeExtensions.cs" />
+    <Compile Include="ValueReturningVisitor.cs" />
+    <Compile Include="Visitable.cs" />
+    <Compile Include="Visitor.cs" />
+    <Compile Include="VisitorExtensions.cs" />
+    <Compile Include="Year.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file
product/utility/ValueReturningVisitor.cs
@@ -0,0 +1,8 @@
+namespace utility
+{
+    public interface ValueReturningVisitor<Value, T> : Visitor<T>
+    {
+        Value value { get; }
+        void reset();
+    }
+}
\ No newline at end of file
product/utility/Visitable.cs
@@ -0,0 +1,7 @@
+namespace utility
+{
+    public interface Visitable<T>
+    {
+        void accept(Visitor<T> visitor);
+    }
+}
\ No newline at end of file
product/utility/Visitor.cs
@@ -0,0 +1,7 @@
+namespace utility
+{
+    public interface Visitor<T>
+    {
+        void visit(T item_to_visit);
+    }
+}
\ No newline at end of file
product/utility/VisitorExtensions.cs
@@ -0,0 +1,19 @@
+using System.Collections.Generic;
+
+namespace utility
+{
+    static public class VisitorExtensions
+    {
+        static public Result return_value_from_visiting_all_with<Result, T>(this IEnumerable<T> items, ValueReturningVisitor<Result, T> visitor)
+        {
+            visitor.reset();
+            items.vist_all_with(visitor);
+            return visitor.value;
+        }
+
+        static public void vist_all_with<T>(this IEnumerable<T> items, Visitor<T> visitor)
+        {
+            items.each(visitor.visit);
+        }
+    }
+}
\ No newline at end of file
product/utility/Year.cs
@@ -0,0 +1,53 @@
+using System;
+
+namespace utility
+{
+    public class Year
+    {
+        readonly int the_underlying_year;
+
+        public Year(int year) : this(new DateTime(year, 01, 01))
+        {
+        }
+
+        public Year(DateTime date)
+        {
+            the_underlying_year = date.Year;
+        }
+
+        static public implicit operator Year(int year)
+        {
+            return new Year(year);
+        }
+
+        public bool Equals(Year obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            return obj.the_underlying_year == the_underlying_year;
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != typeof (Year)) return false;
+            return Equals((Year) obj);
+        }
+
+        public override int GetHashCode()
+        {
+            return the_underlying_year;
+        }
+
+        public bool represents(DateTime time)
+        {
+            return time.Year.Equals(the_underlying_year);
+        }
+
+        public override string ToString()
+        {
+            return the_underlying_year.ToString();
+        }
+    }
+}
\ No newline at end of file
studio.sln
@@ -5,6 +5,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "desktop.ui", "product\deskt
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "specs", "product\specs\specs.csproj", "{B10E4560-2546-4A11-B2D1-5505BFCDDCC9}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "infrastructure", "product\infrastructure\infrastructure.csproj", "{CC006EB6-4E3C-4497-B8CC-5CAF54E40113}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "utility", "product\utility\utility.csproj", "{39B95E47-DA9C-4C80-A395-515600C55D4B}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -35,6 +39,26 @@ Global
 		{B10E4560-2546-4A11-B2D1-5505BFCDDCC9}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
 		{B10E4560-2546-4A11-B2D1-5505BFCDDCC9}.Release|Mixed Platforms.Build.0 = Release|Any CPU
 		{B10E4560-2546-4A11-B2D1-5505BFCDDCC9}.Release|x86.ActiveCfg = Release|Any CPU
+		{CC006EB6-4E3C-4497-B8CC-5CAF54E40113}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{CC006EB6-4E3C-4497-B8CC-5CAF54E40113}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{CC006EB6-4E3C-4497-B8CC-5CAF54E40113}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+		{CC006EB6-4E3C-4497-B8CC-5CAF54E40113}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+		{CC006EB6-4E3C-4497-B8CC-5CAF54E40113}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{CC006EB6-4E3C-4497-B8CC-5CAF54E40113}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{CC006EB6-4E3C-4497-B8CC-5CAF54E40113}.Release|Any CPU.Build.0 = Release|Any CPU
+		{CC006EB6-4E3C-4497-B8CC-5CAF54E40113}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+		{CC006EB6-4E3C-4497-B8CC-5CAF54E40113}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+		{CC006EB6-4E3C-4497-B8CC-5CAF54E40113}.Release|x86.ActiveCfg = Release|Any CPU
+		{39B95E47-DA9C-4C80-A395-515600C55D4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{39B95E47-DA9C-4C80-A395-515600C55D4B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{39B95E47-DA9C-4C80-A395-515600C55D4B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+		{39B95E47-DA9C-4C80-A395-515600C55D4B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+		{39B95E47-DA9C-4C80-A395-515600C55D4B}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{39B95E47-DA9C-4C80-A395-515600C55D4B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{39B95E47-DA9C-4C80-A395-515600C55D4B}.Release|Any CPU.Build.0 = Release|Any CPU
+		{39B95E47-DA9C-4C80-A395-515600C55D4B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+		{39B95E47-DA9C-4C80-A395-515600C55D4B}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+		{39B95E47-DA9C-4C80-A395-515600C55D4B}.Release|x86.ActiveCfg = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE