Commit e2c1e66

mokhan <mokhan@ce5e1baf-6525-42e4-a1b2-857ea38da20a>
2009-05-05 03:40:49
working on security and specifications support.
git-svn-id: https://svn.xp-dev.com/svn/mokhan-mo.money@203 ce5e1baf-6525-42e4-a1b2-857ea38da20a
1 parent 87ab8a3
trunk/build/build_utilities.rb
@@ -0,0 +1,187 @@
+include FileTest
+
+class SqlRunner
+  def initialize(settings = Hash.new("Not found"))
+    @sql_tool = settings.fetch(:sql_tool,File.join(ENV['SystemDrive'],'program files','microsoft sql server','100','tools','binn','osql.exe'))
+    @command_line_args = settings.fetch(:command_line_args, '-b -i')
+    @connection_string = settings.fetch(:connection_string,"-E")
+  end
+
+  def process_sql_files(files)
+      files.each do|file|
+        begin
+            sh "#{@sql_tool} #{@connection_string} #{@command_line_args} #{file}"
+        rescue 
+          puts("Error processing sql file:#{file}")
+          raise
+        end
+      end
+  end
+end
+
+class LocalSettings
+  attr_reader :settings
+
+  def [](setting)
+    @settings[setting]
+  end
+
+  def each_pair
+    @settings.each_key do|key,value|
+      yield key,@settings[key]
+    end
+  end
+end
+
+class TemplateFile
+  attr_reader :template_file_name
+  attr_reader :output_file_name
+
+  def initialize(template_file_name)
+    @template_file_name = template_file_name
+    @output_file_name = template_file_name.gsub('.template','')
+  end
+
+  def generate(settings_dictionary)
+    generate_to(@output_file_name,settings_dictionary)
+  end
+
+  def generate_to_directory(output_directory,settings_dictionary)
+    generate_to(File.join(output_directory,File.basename(@output_file_name)),settings_dictionary)
+  end
+
+  def generate_to_directories(output_directories,settings_dictionary)
+    output_directories.each do |directory|
+      generate_to_directory(directory,settings_dictionary)
+    end
+  end
+
+  def generate_to(output_file,settings_dictionary)
+     File.delete?(output_file) 
+
+     File.open_for_write(output_file) do|generated_file|
+       File.open_for_read(@template_file_name) do|template_line|
+         settings_dictionary.each_key do|key|
+           template_line = template_line.gsub("@#{key}@","#{settings_dictionary[key]}")
+         end
+         generated_file.puts(template_line)
+       end
+     end
+  end
+
+  def to_s()
+    "Template File- Template:#{@template_file_name} : Output:#{@output_file_name}"
+  end
+
+end
+
+class TemplateFileList
+  @template_files
+  def initialize(files_pattern)
+    @template_files  = []
+    FileList.new(files_pattern).each do|file| 
+      @template_files.push(TemplateFile.new(file))
+    end
+  end
+
+  def each()
+    @template_files.each do |file|
+      yield file
+    end
+  end
+
+  def generate_all_output_files(settings)
+    @template_files.each do |file|
+      file.generate(settings)
+    end
+  end
+end
+
+class MbUnitRunner
+	def initialize(items)
+		@source_dir = items.fetch(:source_dir, 'product')
+		@mbunit_dir = items.fetch(:mbunit_dir, 'tools/gallio')
+		@test_results_dir = items.fetch(:test_results_dir, 'artifacts')
+		@compile_target = items.fetch(:compile_target, 'debug')
+		@category_to_exclude = items.fetch(:category_to_exclude, 'missing')
+		@show_report = items.fetch(:show_report, false)
+		@report_type = items.fetch(:report_type,'text')
+	end
+	
+	def execute_tests(assemblies)
+		Dir.mkdir @test_results_dir unless exists?(@test_results_dir)
+		
+		assemblies.each do |assem|
+		  sh build_command_line_for(assem)
+		end
+	end
+
+  def build_command_line_for(assembly)
+		file = File.expand_path("#{@source_dir}/#{assembly}/bin/#{@compile_target}/#{assembly}.dll")
+	  "#{@mbunit_dir}/gallio.echo.exe #{file} /sr /rt:#{@report_type} /rd:#{@test_results_dir} /rnf:#{assembly}.dll-results "
+  end
+end
+
+class MSBuildRunner
+	def self.compile(attributes)
+		version = attributes.fetch(:clrversion, 'v3.5')
+		compile_target = attributes.fetch(:compile_target, 'debug')
+	    solution_file = attributes[:solution_file]
+		
+		framework_dir = File.join(ENV['windir'].dup, 'Microsoft.NET', 'Framework', 'v3.5')
+		msbuild_file = File.join(framework_dir, 'msbuild.exe')
+		
+		sh "#{msbuild_file} #{solution_file} /property:Configuration=#{compile_target} /t:Rebuild"
+	end
+end
+
+class File
+  def self.open_for_read(file)
+     File.open(file,'r').each do|line|
+       yield line
+     end
+  end
+
+  def self.read_all_text(file)
+    contents = ''
+    File.open_for_read(file) do |line|
+      contents += line
+    end
+  end
+
+  def self.delete?(file)
+    File.delete(file) if File.exists?(file)
+  end
+
+  def self.open_for_write(file)
+     File.open(file,'w') do|new_file|
+       yield new_file
+     end
+  end
+
+  def self.base_name_without_extensions(file)
+    File.basename(file,'.*')
+  end
+
+ end
+
+class BDDDocRunner
+  def initialize(settings = Hash.new('missing'))
+    @output_folder = settings.fetch(:output_folder,'artifacts')
+    @observation_attribute = settings.fetch(:observation_attribute,'ObservationAttribute')
+    @bdddoc_folder = settings.fetch(:bdddoc_folder,'thirdparty\developwithpassion.bdddoc')
+    @mbunit_test_output_folder = settings.fetch(:mbunit_test_output_folder,'artifacts')
+    @developwithpassion_bdddoc_exe = settings.fetch(:bdddoc_exe,'developwithpassion.bdddoc.exe')
+    @logo_jpg = settings.fetch(:logo_jpg,File.join(@bdddoc_folder,'developwithpassion.bdddoc-logo.jpg'))
+    @css = settings.fetch(:css,File.join(@bdddoc_folder,'developwithpassion.bdddoc.css'))
+  end
+
+  def run(test_library)
+    test_file = File.basename(test_library)
+    output_file = "#{File.join(@output_folder,test_file)}.developwithpassion.bdddoc.html"
+    mbunit_test_output_file = "#{File.join(@mbunit_test_output_folder,test_file)}-results.xml"
+    sh "#{File.join(@bdddoc_folder,@developwithpassion_bdddoc_exe)} #{test_library} #{@observation_attribute} #{output_file} #{mbunit_test_output_file}"
+   FileUtils.cp @logo_jpg,@output_folder
+   FileUtils.cp @css,@output_folder
+  end
+end
trunk/build/Empty.cs
@@ -0,0 +1,7 @@
+namespace MyMoney.Build
+{
+    public class Empty
+    {
+        
+    }
+}
\ No newline at end of file
trunk/build/local_properties.rb
@@ -0,0 +1,33 @@
+require "project_name.rb"
+
+class LocalSettings 
+  attr_reader :settings
+ def initialize
+  @settings = {
+  	:app_config_template => 'app.config.xp.template' ,
+  	#:app_config_template => 'app.config.vista.template' ,
+  	:path_to_runtime_log4net_config => 'artifacts\log4net.config.xml',
+  	:initial_catalog => "#{Project.name}",
+  	:database_provider => 'System.Data.SqlClient' ,
+  	:database_path => 'C:\databases' ,
+  	:asp_net_worker_process => 'aspnet_wp.exe',
+  	:log_file_name => "#{Project.name}Log.txt",
+  	:log_level => 'DEBUG',
+  	:xunit_report_file_dir => 'artifacts' ,
+  	:xunit_report_file_name => 'test_report',
+  	:xunit_report_type => 'text',
+  	:xunit_show_test_report => true,
+  	:debug => true,
+  }
+@settings[:xunit_report_file_name_with_extension] = "#{@settings[:xunit_report_file_name]}.#{@settings[:xunit_report_type]}"
+@settings[:asp_net_account] = "#{ENV["computername"]}\\ASPNet";
+#@settings[:db_account_sql]= "#{@settings[:asp_net_account]} WITH PASSWORD=N'#{@settings[:asp_net_account]}', DEFAULT_DATABASE=[master], DEFAULT_LANGUAGE=[us_english], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF")
+@settings[:db_account_sql] = "#{@settings[:asp_net_account]}', N'#{@settings[:asp_net_account]}'"
+
+#these settings may need to be changed to be specific to your local machine
+@settings[:osql_connectionstring] = '-E'
+@settings[:sql_tools_path] = File.join(ENV['SystemDrive'],'program files/microsoft sql server/100/tools/binn')
+@settings[:osql_exe] = File.join("#{@settings[:sql_tools_path]}",'osql.exe')
+@settings[:config_connectionstring] = "data source=(local);Integrated Security=SSPI;Initial Catalog=#{@settings[:initial_catalog]}"
+ end
+end
trunk/build/MyMoney.Build.csproj
@@ -67,6 +67,9 @@
   <ItemGroup>
     <Content Include="local.properties.xml" />
   </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Empty.cs" />
+  </ItemGroup>
   <ItemGroup>
     <Folder Include="Properties\" />
   </ItemGroup>
trunk/build/project_name.rb
@@ -0,0 +1,8 @@
+class Project
+  attr_reader :name 
+
+  def self.name
+   @name = "momoney"
+  end 
+
+end
trunk/build/rakefile.rb
@@ -0,0 +1,50 @@
+require 'build_utilities.rb'
+require 'local_properties.rb'
+require 'project_name.rb'
+require 'rake/clean'
+require 'fileutils'
+
+#load settings that differ by machine
+local_settings = LocalSettings.new
+
+COMPILE_TARGET = 'debug'
+
+CLEAN.include('artifacts','**/bin','**/obj')
+
+#target folders that can be run from VS
+project_test_dir  = File.join('product',"#{Project.name}.tests",'bin','debug')
+
+output_folders = [project_test_dir]
+
+task :default => [:full_test]
+
+task :init  => :clean do
+  mkdir 'artifacts'
+  mkdir 'artifacts/coverage'
+  mkdir 'artifacts/deploy'
+end
+
+desc 'compiles the project'
+task :compile => :init do
+  MSBuildRunner.compile :compile_target => COMPILE_TARGET, :solution_file => '../solution.sln'
+end
+
+task :deploy => :compile do
+  Dir.glob(File.join('product','**','mo.money*.dll')).each do|file|
+    FileUtils.cp file,File.join('artifacts','deploy')
+  end
+end
+
+desc 'run the tests for the project'
+task :test, :category_to_exclude, :needs => [:compile] do |t,args|
+  args.with_defaults(:category_to_exclude => 'SLOW')
+  runner = MbUnitRunner.new :compile_target => COMPILE_TARGET, :category_to_exclude => args.category_to_exclude
+  runner.execute_tests ["Gorilla.Commons.Infrastructure"]
+end
+
+desc 'run the bdddoc test report for the project'
+task :run_test_report => [:test] do
+ runner = BDDDocRunner.new 
+ runner.run(File.join('product','developwithpassion.bdd.tests','bin','debug','developwithpassion.bdd.tests.dll'))
+end
+
trunk/build/run.bat
@@ -0,0 +1,3 @@
+@echo off
+cls
+rake rakefile.rb %*
trunk/product/Gorilla.Commons.Infrastructure/Cloning/Serializer.cs
@@ -14,17 +14,13 @@ namespace Gorilla.Commons.Infrastructure.Cloning
         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()
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Experiments/Autofac/AutofacContainerBuilder.cs
@@ -1,75 +0,0 @@
-using System;
-using System.Linq.Expressions;
-using Autofac;
-using Autofac.Builder;
-using Autofac.Modules;
-using Autofac.Registrars;
-using AutofacContrib.DynamicProxy2;
-using Gorilla.Commons.Infrastructure.Castle.DynamicProxy;
-using Gorilla.Commons.Infrastructure.Container;
-using Gorilla.Commons.Infrastructure.Experiments;
-using Gorilla.Commons.Utility.Core;
-using Gorilla.Commons.Utility.Extensions;
-
-namespace Gorilla.Commons.Infrastructure.New.Autofac
-{
-    public class AutofacContainerBuilder : IContainerBuilder
-    {
-        readonly ContainerBuilder builder;
-        readonly Func<IContainer> container;
-
-        public AutofacContainerBuilder() : this(new ContainerBuilder())
-        {
-        }
-
-        public AutofacContainerBuilder(ContainerBuilder builder)
-        {
-            this.builder = builder;
-            builder.RegisterModule(new ImplicitCollectionSupportModule());
-            builder.RegisterModule(new StandardInterceptionModule());
-            builder.SetDefaultScope(InstanceScope.Factory);
-            container = () => builder.Build();
-            container = container.memorize();
-        }
-
-        public IDependencyRegistry build()
-        {
-            throw new NotImplementedException();
-        }
-
-        public IExtendedRegistration<T> register<T>(Expression<Func<T>> func) where T : class
-        {
-            return new AutofacExtendedRegistration<T>(builder, func);
-        }
-    }
-
-    public class AutofacExtendedRegistration<T> :  IExtendedRegistration<T> where T : class
-    {
-        IConcreteRegistrar registrar;
-
-        public AutofacExtendedRegistration(ContainerBuilder builder, Expression<Func<T>> expression)
-        {
-            pretty_print = expression.ToString();
-            registrar = builder.Register(x => expression.Compile()).As<T>();
-            registrar.FactoryScoped();
-        }
-
-        public string pretty_print { get; set; }
-
-        public IExtendedRegistration<T> as_singleton()
-        {
-            registrar.SingletonScoped();
-            return this;
-        }
-
-        public IExtendedRegistration<T> with_expiry(string date_time)
-        {
-            throw new NotImplementedException();
-        }
-
-        public IExtendedRegistration<T> with_proxy(IConfiguration<IProxyBuilder<T>> configuration)
-        {
-            throw new NotImplementedException();
-        }
-    }
-}
\ No newline at end of file
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Experiments/ExtendedRegistration.cs
@@ -1,57 +0,0 @@
-using System;
-using System.Globalization;
-using System.Linq.Expressions;
-using Gorilla.Commons.Infrastructure.Castle.DynamicProxy;
-using Gorilla.Commons.Utility;
-using Gorilla.Commons.Utility.Core;
-using Gorilla.Commons.Utility.Extensions;
-
-namespace Gorilla.Commons.Infrastructure.Experiments
-{
-    public class ExtendedRegistration<T> : IResolver<T>, IExtendedRegistration<T> where T : class
-    {
-        public Func<T> build { get; private set; }
-        const string time_format = "dd/MM/yyyy HH:mm:ss";
-
-        public ExtendedRegistration(Expression<Func<T>> expression)
-        {
-            pretty_print = expression.ToString();
-            build = expression.Compile();
-        }
-
-        public string pretty_print { get; set; }
-
-        public IExtendedRegistration<T> as_singleton()
-        {
-            build = build.memorize();
-            return this;
-        }
-
-        public IExtendedRegistration<T> with_expiry(string date_time)
-        {
-            var the_date_time = DateTime.ParseExact(date_time, time_format, CultureInfo.InvariantCulture);
-            var original_func = build;
-
-            build = () =>
-                        {
-                            if (Clock.now() > the_date_time)
-                                throw new ObjectUsageHasExpiredException(original_func().GetType(), date_time);
-
-                            return original_func();
-                        };
-            return this;
-        }
-
-        public IExtendedRegistration<T> with_proxy(IConfiguration<IProxyBuilder<T>> configuration)
-        {
-            var original_func = build;
-            build = () =>
-                        {
-                            var builder = new ProxyBuilder<T>();
-                            configuration.configure(builder);
-                            return builder.create_proxy_for(original_func);
-                        };
-            return this;
-        }
-    }
-}
\ No newline at end of file
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Experiments/IContainerBuilder.cs
@@ -1,12 +0,0 @@
-using System;
-using System.Linq.Expressions;
-using Gorilla.Commons.Infrastructure.Container;
-using Gorilla.Commons.Utility.Core;
-
-namespace Gorilla.Commons.Infrastructure.Experiments
-{
-    public interface IContainerBuilder : IBuilder<IDependencyRegistry>
-    {
-        IExtendedRegistration<T> register<T>(Expression<Func<T>> func) where T : class;
-    }
-}
\ No newline at end of file
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Experiments/IExtendedRegistration.cs
@@ -1,17 +0,0 @@
-using Gorilla.Commons.Infrastructure.Castle.DynamicProxy;
-using Gorilla.Commons.Utility.Core;
-
-namespace Gorilla.Commons.Infrastructure.Experiments
-{
-    public interface IExtendedRegistration
-    {
-        string pretty_print { get; }
-    }
-
-    public interface IExtendedRegistration<T> : IExtendedRegistration where T : class
-    {
-        IExtendedRegistration<T> as_singleton();
-        IExtendedRegistration<T> with_expiry(string date_time);
-        IExtendedRegistration<T> with_proxy(IConfiguration<IProxyBuilder<T>> configuration);
-    }
-}
\ No newline at end of file
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Experiments/IResolver.cs
@@ -1,9 +0,0 @@
-using System;
-
-namespace Gorilla.Commons.Infrastructure.Experiments
-{
-    public interface IResolver<T>
-    {
-        Func<T> build { get; }
-    }
-}
\ No newline at end of file
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Experiments/ObjectUsageHasExpiredException.cs
@@ -1,16 +0,0 @@
-using System;
-
-namespace Gorilla.Commons.Infrastructure.Experiments
-{
-    internal class ObjectUsageHasExpiredException : Exception
-    {
-        public ObjectUsageHasExpiredException(Type type, string date_time) : base(build_message(type, date_time))
-        {
-        }
-
-        static string build_message(Type type, string date_time)
-        {
-            return string.Format("Cannot use {0} after {1}.", type.Name, date_time);
-        }
-    }
-}
\ No newline at end of file
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Experiments/SimpleContainerBuilder.cs
@@ -1,31 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq.Expressions;
-using Gorilla.Commons.Infrastructure.Container;
-
-namespace Gorilla.Commons.Infrastructure.Experiments
-{
-    public class SimpleContainerBuilder : IContainerBuilder
-    {
-        readonly IDictionary<Type, IExtendedRegistration> registries = new Dictionary<Type, IExtendedRegistration>();
-
-        public IDependencyRegistry build()
-        {
-            return new SimpleRegistry(registries);
-        }
-
-        public IExtendedRegistration<T> register<T>(Expression<Func<T>> func) where T : class
-        {
-            try
-            {
-                var registration = new ExtendedRegistration<T>(func);
-                registries.Add(typeof (T), registration);
-                return registration;
-            }
-            catch (ArgumentException e)
-            {
-                throw new TypeAlreadyRegisteredInContainerException(typeof (T), registries[typeof (T)].pretty_print);
-            }
-        }
-    }
-}
\ No newline at end of file
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Experiments/SimpleRegistry.cs
@@ -1,34 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Gorilla.Commons.Infrastructure.Container;
-using Gorilla.Commons.Utility.Extensions;
-
-namespace Gorilla.Commons.Infrastructure.Experiments
-{
-    public class SimpleRegistry : IDependencyRegistry
-    {
-        readonly IDictionary<Type, IList<IExtendedRegistration>> registrations;
-
-        public SimpleRegistry(IDictionary<Type, IList<IExtendedRegistration>> registrations)
-        {
-            this.registrations = registrations;
-        }
-
-        public Interface get_a<Interface>()
-        {
-            return registrations[typeof (Interface)].First().downcast_to<IResolver<Interface>>().build();
-        }
-
-        public IEnumerable<Interface> all_the<Interface>()
-        {
-            foreach (var registration in registrations[typeof(Interface)])
-            {
-                yield return registration.downcast_to<IResolver<Interface>>().build()
-
-                
-            }
-            yield return registrations[typeof(Interface)].each(x => x.downcast_to<IResolver<Interface>>().build());
-        }
-    }
-}
\ No newline at end of file
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Experiments/TypeAlreadyRegisteredInContainerException.cs
@@ -1,18 +0,0 @@
-using System;
-
-namespace Gorilla.Commons.Infrastructure.Experiments
-{
-    public class TypeAlreadyRegisteredInContainerException : Exception
-    {
-        public TypeAlreadyRegisteredInContainerException(Type typeNotFound, string registration)
-            : base(build_message(typeNotFound, registration))
-        {
-        }
-
-        static string build_message(Type typeNotFound, string registration)
-        {
-            return string.Format("The type {0} has already been registered with {1} in the container",
-                                 typeNotFound.FullName, registration);
-        }
-    }
-}
\ No newline at end of file
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Gorilla.Commons.Infrastructure.ThirdParty.csproj
@@ -131,15 +131,6 @@
     <Compile Include="Castle\Windsor\WindsorContainerFactory.cs" />
     <Compile Include="Castle\Windsor\WindsorDependencyRegistry.cs" />
     <Compile Include="Castle\Windsor\WindsorDependencyRegistrySpecs.cs" />
-    <Compile Include="Experiments\Autofac\AutofacContainerBuilder.cs" />
-    <Compile Include="Experiments\ExtendedRegistration.cs" />
-    <Compile Include="Experiments\IContainerBuilder.cs" />
-    <Compile Include="Experiments\IExtendedRegistration.cs" />
-    <Compile Include="Experiments\IResolver.cs" />
-    <Compile Include="Experiments\ObjectUsageHasExpiredException.cs" />
-    <Compile Include="Experiments\SimpleContainerBuilder.cs" />
-    <Compile Include="Experiments\SimpleRegistry.cs" />
-    <Compile Include="Experiments\TypeAlreadyRegisteredInContainerException.cs" />
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\Gorilla.Commons.Infrastructure\Gorilla.Commons.Infrastructure.csproj">
trunk/product/Gorilla.Commons.Utility/Core/NotSpecification.cs
@@ -0,0 +1,17 @@
+namespace Gorilla.Commons.Utility.Core
+{
+    public class NotSpecification<T> : ISpecification<T>
+    {
+        readonly ISpecification<T> item_to_match;
+
+        public NotSpecification(ISpecification<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
trunk/product/Gorilla.Commons.Utility/Core/NotSpecificationSpecs.cs
@@ -0,0 +1,43 @@
+using developwithpassion.bdd.contexts;
+using Gorilla.Commons.Testing;
+
+namespace Gorilla.Commons.Utility.Core
+{
+    public class NotSpecificationSpecs
+    {
+    }
+
+    public class when_checking_if_a_condition_is_not_met : concerns_for<ISpecification<int>, NotSpecification<int>>
+    {
+        static protected ISpecification<int> criteria;
+
+        context c = () => { criteria = the_dependency<ISpecification<int>>(); };
+
+        public override ISpecification<int> create_sut()
+        {
+            return new NotSpecification<int>(criteria);
+        }
+    }
+
+    public class when_a_condition_is_not_met : when_checking_if_a_condition_is_not_met
+    {
+        context c = () => when_the(criteria).is_told_to(x => x.is_satisfied_by(1)).it_will_return(false);
+
+        because b = () => { result = sut.is_satisfied_by(1); };
+
+        it should_return_true = () => result.should_be_true();
+
+        static bool result;
+    }
+
+    public class when_a_condition_is_met : when_checking_if_a_condition_is_not_met
+    {
+        context c = () => when_the(criteria).is_told_to(x => x.is_satisfied_by(1)).it_will_return(true);
+
+        because b = () => { result = sut.is_satisfied_by(1); };
+
+        it should_return_false = () => result.should_be_false();
+
+        static bool result;
+    }
+}
\ No newline at end of file
trunk/product/Gorilla.Commons.Utility/Extensions/EnumerableExtensions.cs
@@ -4,43 +4,36 @@ using System.Linq;
 
 namespace Gorilla.Commons.Utility.Extensions
 {
-    public static class EnumerableExtensions
+    static public class EnumerableExtensions
     {
-        public static IEnumerable<T> where<T>(this IEnumerable<T> items, Func<T, bool> condition_is_met)
+        static public IEnumerable<T> where<T>(this IEnumerable<T> items, Func<T, bool> condition_is_met)
         {
-            return null == items ? new List<T>() : items.Where(condition_is_met);
+            return null == items ? Enumerable.Empty<T>() : items.Where(condition_is_met);
         }
 
-        public static IList<T> databind<T>(this IEnumerable<T> items_to_bind_to)
+        static public IList<T> databind<T>(this IEnumerable<T> items_to_bind_to)
         {
-            return items_to_bind_to.ToList();
+            return null == items_to_bind_to ? new List<T>() : items_to_bind_to.ToList();
         }
 
-        public static 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;
-        }
-
-        public static IEnumerable<T> sorted_using<T>(this IEnumerable<T> items_to_sort, IComparer<T> sorting_algorithm)
+        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);
             sorted_items.Sort(sorting_algorithm);
             return sorted_items;
         }
 
-        public static IEnumerable<T> all<T>(this IEnumerable<T> items)
+        static public IEnumerable<T> all<T>(this IEnumerable<T> items)
         {
-            foreach (var item in items ?? new List<T>()) yield return item;
+            foreach (var item in items ?? Enumerable.Empty<T>()) yield return item;
         }
 
-        public static void each<T>(this IEnumerable<T> items, Action<T> action)
+        static public void each<T>(this IEnumerable<T> items, Action<T> action)
         {
-            foreach (var item in items ?? new List<T>()) action(item);
+            foreach (var item in items ?? Enumerable.Empty<T>()) action(item);
         }
 
-        public static IEnumerable<T> join_with<T>(this IEnumerable<T> left, IEnumerable<T> right)
+        static public IEnumerable<T> join_with<T>(this IEnumerable<T> left, IEnumerable<T> right)
         {
             if (null == right) return left;
 
trunk/product/Gorilla.Commons.Utility/Extensions/SpecificationExtensions.cs
@@ -1,10 +1,18 @@
 using System;
+using System.Collections.Generic;
 using Gorilla.Commons.Utility.Core;
 
 namespace Gorilla.Commons.Utility.Extensions
 {
     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);
@@ -24,5 +32,10 @@ namespace Gorilla.Commons.Utility.Extensions
         {
             return new OrSpecification<T>(left, right);
         }
+
+        static public ISpecification<T> not<T>(this ISpecification<T> original)
+        {
+            return new NotSpecification<T>(original);
+        }
     }
 }
\ No newline at end of file
trunk/product/Gorilla.Commons.Utility/Gorilla.Commons.Utility.csproj
@@ -89,6 +89,8 @@
     <Compile Include="Core\IVisitable.cs" />
     <Compile Include="Core\IVisitor.cs" />
     <Compile Include="Core\Mapper.cs" />
+    <Compile Include="Core\NotSpecification.cs" />
+    <Compile Include="Core\NotSpecificationSpecs.cs" />
     <Compile Include="Core\OrSpecification.cs" />
     <Compile Include="Core\OrSpecificationSpecs.cs" />
     <Compile Include="Core\PredicateSpecification.cs" />
trunk/product/MoMoney.Service/Infrastructure/Security/IsInRole.cs
@@ -0,0 +1,20 @@
+using System.Security.Principal;
+using Gorilla.Commons.Utility.Core;
+
+namespace MoMoney.Service.Infrastructure.Security
+{
+    public class IsInRole : ISpecification<IPrincipal>
+    {
+        readonly Role role;
+
+        public IsInRole(Role role)
+        {
+            this.role = role;
+        }
+
+        public bool is_satisfied_by(IPrincipal item)
+        {
+            return item.IsInRole(role);
+        }
+    }
+}
\ No newline at end of file
trunk/product/MoMoney.Service/Infrastructure/Security/IsInRoleSpecs.cs
@@ -0,0 +1,56 @@
+using System.Security.Principal;
+using developwithpassion.bdd.contexts;
+using Gorilla.Commons.Testing;
+using Gorilla.Commons.Utility.Core;
+using MoMoney.Service.Infrastructure.Security;
+
+public class IsInRoleSpecs
+{
+}
+
+public class when_checking_if_a_principal_belongs_to_a_role :
+    concerns_for<ISpecification<IPrincipal>, IsInRole>
+{
+    static protected readonly Role administrator_role = new Role("administrators");
+
+    public override ISpecification<IPrincipal> create_sut()
+    {
+        return new IsInRole(administrator_role);
+    }
+}
+
+public class when_not_in_one_of_the_roles : when_checking_if_a_principal_belongs_to_a_role
+{
+    context c = () =>
+                    {
+                        principal = the_dependency<IPrincipal>();
+                        when_the(principal)
+                            .is_told_to(x => x.IsInRole(administrator_role))
+                            .it_will_return(false);
+                    };
+
+    because b = () => { result = sut.is_satisfied_by(principal); };
+
+    it should_return_false = () => result.should_be_false();
+
+    static bool result;
+    static IPrincipal principal;
+}
+
+public class when_in_one_of_the_roles : when_checking_if_a_principal_belongs_to_a_role
+{
+    context c = () =>
+                    {
+                        principal = the_dependency<IPrincipal>();
+                        when_the(principal)
+                            .is_told_to(x => x.IsInRole(administrator_role))
+                            .it_will_return(true);
+                    };
+
+    because b = () => { result = sut.is_satisfied_by(principal); };
+
+    it should_return_true = () => result.should_be_true();
+
+    static bool result;
+    static IPrincipal principal;
+}
\ No newline at end of file
trunk/product/MoMoney.Service/Infrastructure/Security/Role.cs
@@ -0,0 +1,42 @@
+namespace MoMoney.Service.Infrastructure.Security
+{
+    public class Role
+    {
+        readonly string name;
+
+        public Role(string name)
+        {
+            this.name = name;
+        }
+
+        static public implicit operator string(Role role)
+        {
+            return role.name;
+        }
+
+        static public implicit operator Role(string role)
+        {
+            return new Role(role);
+        }
+
+        public bool Equals(Role other)
+        {
+            if (ReferenceEquals(null, other)) return false;
+            if (ReferenceEquals(this, other)) return true;
+            return Equals(other.name, name);
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != typeof (Role)) return false;
+            return Equals((Role) obj);
+        }
+
+        public override int GetHashCode()
+        {
+            return (name != null ? name.GetHashCode() : 0);
+        }
+    }
+}
\ No newline at end of file
trunk/product/MoMoney.Service/MoMoney.Service.csproj
@@ -83,6 +83,9 @@
     <Compile Include="Application\SaveNewBillCommand.cs" />
     <Compile Include="Infrastructure\Logging\LogFileTasks.cs" />
     <Compile Include="Infrastructure\ProjectTasks.cs" />
+    <Compile Include="Infrastructure\Security\IsInRole.cs" />
+    <Compile Include="Infrastructure\Security\IsInRoleSpecs.cs" />
+    <Compile Include="Infrastructure\Security\Role.cs" />
     <Compile Include="Infrastructure\Updating\CancelUpdate.cs" />
     <Compile Include="Infrastructure\Updating\CancelUpdateSpecs.cs" />
     <Compile Include="Infrastructure\Updating\CurrentDeployment.cs" />
trunk/product/MyMoney/boot/container/registration/proxy_configuration/InterceptingFilter.cs
@@ -0,0 +1,24 @@
+using System.Security.Principal;
+using System.Threading;
+using Castle.Core.Interceptor;
+using Gorilla.Commons.Infrastructure.Logging;
+using Gorilla.Commons.Utility.Core;
+
+namespace MoMoney.boot.container.registration.proxy_configuration
+{
+    public class InterceptingFilter : IInterceptor
+    {
+        readonly ISpecification<IPrincipal> filter;
+
+        public InterceptingFilter(ISpecification<IPrincipal> filter)
+        {
+            this.filter = filter;
+        }
+
+        public void Intercept(IInvocation invocation)
+        {
+            if (filter.is_satisfied_by(Thread.CurrentPrincipal)) invocation.Proceed();
+            else this.log().debug("call to {0} was blocked");
+        }
+    }
+}
\ No newline at end of file
trunk/product/MyMoney/boot/container/registration/proxy_configuration/InterceptingFilterSpecs.cs
@@ -0,0 +1,57 @@
+using System.Security.Principal;
+using System.Threading;
+using Castle.Core.Interceptor;
+using developwithpassion.bdd.contexts;
+using Gorilla.Commons.Testing;
+using Gorilla.Commons.Utility.Core;
+
+namespace MoMoney.boot.container.registration.proxy_configuration
+{
+    public class InterceptingFilterSpecs
+    {
+    }
+
+    public class when_attempting_to_perform_an_action_that_requires_authentication :
+        concerns_for< InterceptingFilter>
+    {
+        context c = () => { filter = the_dependency<ISpecification<IPrincipal>>(); };
+
+        static protected ISpecification<IPrincipal> filter;
+    }
+
+    public class when_logged_in_as_a_user_that_belongs_to_the_proper_role :
+        when_attempting_to_perform_an_action_that_requires_authentication
+    {
+        context c = () =>
+                        {
+                            invocation = an<IInvocation>();
+                            when_the(filter)
+                                .is_told_to(x => x.is_satisfied_by(Thread.CurrentPrincipal))
+                                .it_will_return(true);
+                        };
+
+        because b = () => sut.Intercept(invocation);
+
+        it should_proceed_with_request = () => invocation.was_told_to(x => x.Proceed());
+
+        static IInvocation invocation;
+    }
+
+    public class when_not_logged_in_as_a_user_that_belongs_to_the_proper_role :
+        when_attempting_to_perform_an_action_that_requires_authentication
+    {
+        context c = () =>
+                        {
+                            invocation = an<IInvocation>();
+                            when_the(filter)
+                                .is_told_to(x => x.is_satisfied_by(Thread.CurrentPrincipal))
+                                .it_will_return(false);
+                        };
+
+        because b = () => sut.Intercept(invocation);
+
+        it should_not_proceed_with_request = () => invocation.was_not_told_to(x => x.Proceed());
+
+        static IInvocation invocation;
+    }
+}
\ No newline at end of file
trunk/product/MyMoney/boot/container/registration/proxy_configuration/ServiceLayerConfiguration.cs
@@ -2,6 +2,8 @@ using Gorilla.Commons.Infrastructure;
 using Gorilla.Commons.Infrastructure.Castle.DynamicProxy;
 using Gorilla.Commons.Infrastructure.Castle.DynamicProxy.Interceptors;
 using Gorilla.Commons.Utility.Core;
+using Gorilla.Commons.Utility.Extensions;
+using MoMoney.Service.Infrastructure.Security;
 
 namespace MoMoney.boot.container.registration.proxy_configuration
 {
@@ -10,6 +12,10 @@ namespace MoMoney.boot.container.registration.proxy_configuration
         public void configure(IProxyBuilder<T> item)
         {
             item.add_interceptor(Lazy.load<IUnitOfWorkInterceptor>()).intercept_all();
+            item.add_interceptor(
+                new InterceptingFilter(new IsInRole("Users")
+                                           .and(new IsInRole("Administrators"))))
+                .intercept_all();
         }
     }
 }
\ No newline at end of file
trunk/product/MyMoney/MyMoney.csproj
@@ -188,6 +188,8 @@
     <Compile Include="boot\container\registration\mapping\PropertyResolver.cs" />
     <Compile Include="boot\container\registration\mapping\TargetActionFactory.cs" />
     <Compile Include="boot\container\registration\proxy_configuration\NoConfiguration.cs" />
+    <Compile Include="boot\container\registration\proxy_configuration\InterceptingFilter.cs" />
+    <Compile Include="boot\container\registration\proxy_configuration\InterceptingFilterSpecs.cs" />
     <Compile Include="boot\container\registration\proxy_configuration\ServiceLayerConfiguration.cs" />
     <Compile Include="boot\container\registration\proxy_configuration\SynchronizedConfiguration.cs" />
     <Compile Include="boot\container\registration\wire_up_the_infrastructure_in_to_the.cs" />