<NME> ValidationState.cs
<BEF> ADDFILE
<MSG> Starting to move more stuff out of StyleMVVM into the grace namespace.

<DFF> @@ -0,0 +1,34 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Grace.Validation
+{
+	/// <summary>
+	/// Represents the validation state for an object or property
+	/// </summary>
+	public enum ValidationState
+	{
+		/// <summary>
+		/// Valid
+		/// </summary>
+		Valid = 1,
+
+		/// <summary>
+		/// Valid but with a warning
+		/// </summary>
+		ValidWithWarning = 2,
+
+		/// <summary>
+		/// Invalid
+		/// </summary>
+		Invalid = 3,
+
+		/// <summary>
+		/// Invalid because it's required and empty
+		/// </summary>
+		InvalidRequired = 4
+	}
+}

{'commit': 'diff --git a/Examples/Grace.ExampleApp/Grace.ExampleApp/DependencyInjection/SpecialTypes/FuncExamples.cs b/Examples/Grace.ExampleApp/Grace.ExampleApp/DependencyInjection/SpecialTypes/FuncExamples.cs\nindex 224002b..3653178 100644\n--- a/Examples/Grace.ExampleApp/Grace.ExampleApp/DependencyInjection/SpecialTypes/FuncExamples.cs\n+++ b/Examples/Grace.ExampleApp/Grace.ExampleApp/DependencyInjection/SpecialTypes/FuncExamples.cs\n@@ -29,4 +29,55 @@ namespace Grace.ExampleApp.DependencyInjection.SpecialTypes\n \t\t\t}\n \t\t}\n \t}\n+\n+\t/// <summary>\n+\t/// This example shows you have to import a Func(Owned(T)) that creates Owned(T) that represent a unit of work\n+\t/// </summary>\n+\tpublic class FuncOwnedExample : IExample<SpecialTypesSubModule>\n+\t{\n+\t\tpublic void ExecuteExample()\n+\t\t{\n+\t\t\tDependencyInjectionContainer container = new DependencyInjectionContainer();\n+\n+\t\t\tcontainer.Configure(c => c.Export<DisposedService>().As<IDisposedService>());\n+\n+\t\t\tFunc<Owned<IDisposedService>> ownedFunc = container.Locate<Func<Owned<IDisposedService>>>();\n+\n+\t\t\tOwned<IDisposedService> owned1 = ownedFunc();\n+\t\t\tOwned<IDisposedService> owned2 = ownedFunc();\n+\n+\t\t\tbool owned1Disposed = false;\n+\t\t\tbool owned2Disposed = false;\n+\n+\t\t\towned1.Value.Disposed += (sender, args) => owned1Disposed = true;\n+\n+\t\t\towned2.Value.Disposed += (sender, args) => owned2Disposed = true;\n+\n+\t\t\towned1.Dispose();\n+\n+\t\t\tif (!owned1Disposed)\n+\t\t\t{\n+\t\t\t\tthrow new Exception("owned1 should have been disposed");\n+\t\t\t}\n+\n+\t\t\tif (owned2Disposed)\n+\t\t\t{\n+\t\t\t\tthrow new Exception("owned2 should not be disposed yet");\n+\t\t\t}\n+\n+\t\t\towned1Disposed = false;\n+\n+\t\t\towned2.Dispose();\n+\n+\t\t\tif (!owned2Disposed)\n+\t\t\t{\n+\t\t\t\tthrow new Exception("owned2 should have been disposed");\n+\t\t\t}\n+\n+\t\t\tif (owned1Disposed)\n+\t\t\t{\n+\t\t\t\tthrow new Exception("owned1Diposed should be false");\n+\t\t\t}\n+\t\t}\n+\t}\n }\ndiff --git a/Source/Grace.Validation/Attributes/AttributeValidationRuleProvider.cs b/Source/Grace.Validation/Attributes/AttributeValidationRuleProvider.cs\nnew file mode 100644\nindex 0000000..02fc33a\n--- /dev/null\n+++ b/Source/Grace.Validation/Attributes/AttributeValidationRuleProvider.cs\n@@ -0,0 +1,62 @@\n+\ufeffusing System;\n+using System.Collections.Generic;\n+using System.Linq;\n+using System.Reflection;\n+using System.Text;\n+using System.Threading.Tasks;\n+\n+namespace Grace.Validation.Attributes\n+{\n+\t/// <summary>\n+\t/// Provides validation rules for an object type based on attributes\n+\t/// </summary>\n+\tpublic class AttributeValidationRuleProvider : IValidationRuleProvider\n+\t{\n+\t\tprivate readonly IReadOnlyCollection<IAttributeValidationRuleProvider> attributeValidationRuleProviders;\n+\n+\t\t/// <summary>\n+\t\t/// Default constructor\n+\t\t/// </summary>\n+\t\t/// <param name="attributeValidationRuleProviders">attribute validation providers</param>\n+\t\tpublic AttributeValidationRuleProvider(\n+\t\t\tIReadOnlyCollection<IAttributeValidationRuleProvider> attributeValidationRuleProviders)\n+\t\t{\n+\t\t\tthis.attributeValidationRuleProviders = attributeValidationRuleProviders;\n+\t\t}\n+\n+\t\tpublic IEnumerable<IValidationRule> ProvideRules(Type objectType, IEnumerable<string> standards)\n+\t\t{\n+\t\t\tList<IValidationRule> returnList = new List<IValidationRule>();\n+\t\t\tList<Attribute> typeAttributes = new List<Attribute>(objectType.GetTypeInfo().GetCustomAttributes());\n+\n+\t\t\tforeach (IAttributeValidationRuleProvider attributeValidationRuleProvider in attributeValidationRuleProviders)\n+\t\t\t{\n+\t\t\t\treturnList.AddRange(attributeValidationRuleProvider.ProvideRules(objectType, typeAttributes, null, null));\n+\t\t\t}\n+\n+\t\t\tforeach (PropertyInfo runtimeProperty in objectType.GetRuntimeProperties())\n+\t\t\t{\n+\t\t\t\tif (!runtimeProperty.CanRead || \n+\t\t\t\t\t !runtimeProperty.GetMethod.IsPublic ||\n+\t\t\t\t\t runtimeProperty.GetMethod.IsStatic)\n+\t\t\t\t{\n+\t\t\t\t\tcontinue;\n+\t\t\t\t}\n+\n+\t\t\t\tforeach (IAttributeValidationRuleProvider attributeValidationRuleProvider in attributeValidationRuleProviders)\n+\t\t\t\t{\n+\t\t\t\t\tList<Attribute> propertyAttributes = new List<Attribute>(runtimeProperty.GetCustomAttributes());\n+\n+\t\t\t\t\treturnList.AddRange(attributeValidationRuleProvider.ProvideRules(objectType, typeAttributes, runtimeProperty, propertyAttributes));\n+\t\t\t\t}\n+\t\t\t}\n+\n+\t\t\treturn returnList;\n+\t\t}\n+\n+\t\tpublic IEnumerable<string> GetPropertiesToValidate(Type objectType, IEnumerable<string> standards)\n+\t\t{\n+\t\t\treturn new string[0];\n+\t\t}\n+\t}\n+}\ndiff --git a/Source/Grace.Validation/Attributes/BaseValidationAttribute.cs b/Source/Grace.Validation/Attributes/BaseValidationAttribute.cs\nnew file mode 100644\nindex 0000000..75d40e5\n--- /dev/null\n+++ b/Source/Grace.Validation/Attributes/BaseValidationAttribute.cs\n@@ -0,0 +1,35 @@\n+\ufeffusing System;\n+using System.Collections.Generic;\n+using System.Linq;\n+using System.Text;\n+using System.Threading.Tasks;\n+\n+namespace Grace.Validation.Attributes\n+{\n+\t/// <summary>\n+\t/// Base validation attribute\n+\t/// </summary>\n+\tpublic abstract class SynchronousBaseValidationAttribute : Attribute, ISyncValidationRule\n+\t{\n+\t\tpublic string Namespace { get; set; }\n+\n+\t\tpublic string DisplayName { get; set; }\n+\n+\t\tpublic string Name { get; private set; }\n+\n+\t\tpublic virtual IEnumerable<string> DependentProperties()\n+\t\t{\n+\t\t\tthrow new NotImplementedException();\n+\t\t}\n+\n+\t\tpublic virtual IEnumerable<string> Standards()\n+\t\t{\n+\t\t\tthrow new NotImplementedException();\n+\t\t}\n+\n+\t\tpublic void Validate(IRuleExecutionContext ruleExecutionContext)\n+\t\t{\n+\t\t\tthrow new NotImplementedException();\n+\t\t}\n+\t}\n+}\ndiff --git a/Source/Grace.Validation/Attributes/CustomAttributeValidationRuleProvider.cs b/Source/Grace.Validation/Attributes/CustomAttributeValidationRuleProvider.cs\nnew file mode 100644\nindex 0000000..80f8148\n--- /dev/null\n+++ b/Source/Grace.Validation/Attributes/CustomAttributeValidationRuleProvider.cs\n@@ -0,0 +1,34 @@\n+\ufeffusing System;\n+using System.Collections.Generic;\n+using System.Linq;\n+using System.Reflection;\n+using System.Text;\n+using System.Threading.Tasks;\n+\n+namespace Grace.Validation.Attributes\n+{\n+\tpublic class CustomAttributeValidationRuleProvider : IAttributeValidationRuleProvider\n+\t{\n+\t\tpublic IEnumerable<IValidationRule> ProvideRules(Type objectType,\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tIEnumerable<Attribute> typeAttributes,\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tPropertyInfo propertyInfo,\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tIEnumerable<Attribute> propertyInfoAttributes)\n+\t\t{\n+\t\t\tif (propertyInfoAttributes != null)\n+\t\t\t{\n+\t\t\t\tforeach (Attribute propertyInfoAttribute in propertyInfoAttributes)\n+\t\t\t\t{\n+\t\t\t\t\tISyncValidationRuleAttribute validationAttribute = propertyInfoAttributes as ISyncValidationRuleAttribute;\n+\n+\t\t\t\t\tif (validationAttribute != null)\n+\t\t\t\t\t{\n+\t\t\t\t\t\tforeach (IValidationRule validationRule in validationAttribute.ProvideValidationRule(objectType, typeAttributes, propertyInfo, propertyInfoAttributes))\n+\t\t\t\t\t\t{\n+\t\t\t\t\t\t\tyield return validationRule;\n+\t\t\t\t\t\t}\n+\t\t\t\t\t}\n+\t\t\t\t}\n+\t\t\t}\n+\t\t}\n+\t}\n+}\ndiff --git a/Source/Grace.Validation/Attributes/ISyncValidationRuleAttribute.cs b/Source/Grace.Validation/Attributes/ISyncValidationRuleAttribute.cs\nnew file mode 100644\nindex 0000000..0d58703\n--- /dev/null\n+++ b/Source/Grace.Validation/Attributes/ISyncValidationRuleAttribute.cs\n@@ -0,0 +1,17 @@\n+\ufeffusing System;\n+using System.Collections.Generic;\n+using System.Linq;\n+using System.Reflection;\n+using System.Text;\n+using System.Threading.Tasks;\n+\n+namespace Grace.Validation.Attributes\n+{\n+\tpublic interface ISyncValidationRuleAttribute\n+\t{\n+\t\tIEnumerable<IValidationRule> ProvideValidationRule(Type objectType,\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tIEnumerable<Attribute> typeAttributes,\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tPropertyInfo propertyInfo,\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tIEnumerable<Attribute> propertyInfoAttributes);\n+\t}\n+}\ndiff --git a/Source/Grace.Validation/CompositionRoot.cs b/Source/Grace.Validation/CompositionRoot.cs\nnew file mode 100644\nindex 0000000..69999fb\n--- /dev/null\n+++ b/Source/Grace.Validation/CompositionRoot.cs\n@@ -0,0 +1,25 @@\n+\ufeffusing System;\n+using System.Collections.Generic;\n+using System.Linq;\n+using System.Text;\n+using System.Threading.Tasks;\n+using Grace.DependencyInjection;\n+\n+namespace Grace.Validation\n+{\n+\t/// <summary>\n+\t/// This class can be used to boot strap the validation engine into the container\n+\t/// </summary>\n+\tpublic class CompositionRoot : IConfigurationModule\n+\t{\n+\t\t/// <summary>\n+\t\t/// Use the validation attributes provided in the Attributes namespace\n+\t\t/// </summary>\n+\t\tpublic bool UseAttributes { get; set; }\n+\n+\t\tpublic void Configure(IExportRegistrationBlock registrationBlock)\n+\t\t{\n+\t\t\t\n+\t\t}\n+\t}\n+}\ndiff --git a/Source/Grace.Validation/Grace.Validation.csproj b/Source/Grace.Validation/Grace.Validation.csproj\nnew file mode 100644\nindex 0000000..99e40ea\n--- /dev/null\n+++ b/Source/Grace.Validation/Grace.Validation.csproj\n@@ -0,0 +1,67 @@\n+\ufeff<?xml version="1.0" encoding="utf-8"?>\n+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\n+  <Import Project="$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props" Condition="Exists(\'$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\')" />\n+  <PropertyGroup>\n+    <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>\n+    <Configuration Condition=" \'$(Configuration)\' == \'\' ">Debug</Configuration>\n+    <Platform Condition=" \'$(Platform)\' == \'\' ">AnyCPU</Platform>\n+    <ProjectGuid>{8D654B69-45DB-47C5-BB82-CE6D02670220}</ProjectGuid>\n+    <OutputType>Library</OutputType>\n+    <AppDesignerFolder>Properties</AppDesignerFolder>\n+    <RootNamespace>Grace.Validation</RootNamespace>\n+    <AssemblyName>Grace.Validation</AssemblyName>\n+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>\n+    <TargetFrameworkProfile>Profile78</TargetFrameworkProfile>\n+    <DefaultLanguage>en-US</DefaultLanguage>\n+    <FileAlignment>512</FileAlignment>\n+    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>\n+  </PropertyGroup>\n+  <PropertyGroup Condition=" \'$(Configuration)|$(Platform)\' == \'Debug|AnyCPU\' ">\n+    <DebugSymbols>true</DebugSymbols>\n+    <DebugType>full</DebugType>\n+    <Optimize>false</Optimize>\n+    <OutputPath>bin\\Debug\\</OutputPath>\n+    <DefineConstants>DEBUG;TRACE</DefineConstants>\n+    <ErrorReport>prompt</ErrorReport>\n+    <WarningLevel>4</WarningLevel>\n+    <DocumentationFile>bin\\Debug\\Grace.Validation.XML</DocumentationFile>\n+  </PropertyGroup>\n+  <PropertyGroup Condition=" \'$(Configuration)|$(Platform)\' == \'Release|AnyCPU\' ">\n+    <DebugType>pdbonly</DebugType>\n+    <Optimize>true</Optimize>\n+    <OutputPath>bin\\Release\\</OutputPath>\n+    <DefineConstants>TRACE</DefineConstants>\n+    <ErrorReport>prompt</ErrorReport>\n+    <WarningLevel>4</WarningLevel>\n+    <DocumentationFile>bin\\Release\\Grace.Validation.XML</DocumentationFile>\n+  </PropertyGroup>\n+  <ItemGroup>\n+    <!-- A reference to the entire .NET Framework is automatically included -->\n+  </ItemGroup>\n+  <ItemGroup>\n+    <Compile Include="Attributes\\AttributeValidationRuleProvider.cs" />\n+    <Compile Include="Attributes\\BaseValidationAttribute.cs" />\n+    <Compile Include="Attributes\\CustomAttributeValidationRuleProvider.cs" />\n+    <Compile Include="Attributes\\ISyncValidationRuleAttribute.cs" />\n+    <Compile Include="CompositionRoot.cs" />\n+    <Compile Include="Impl\\ValidationService.cs" />\n+    <Compile Include="Properties\\AssemblyInfo.cs" />\n+  </ItemGroup>\n+  <ItemGroup>\n+    <ProjectReference Include="..\\Grace\\Grace.csproj">\n+      <Project>{2e64fa60-f2cd-428c-8413-d71b4bf5935a}</Project>\n+      <Name>Grace</Name>\n+    </ProjectReference>\n+  </ItemGroup>\n+  <Import Project="..\\..\\BuildFiles\\Microsoft.Portable.Core.props" Condition="$(teamcity_build_id) != \'\'" />\n+  <Import Project="$(MSBuildToolsPath)\\Microsoft.CSharp.Targets" Condition="$(teamcity_build_id) != \'\'" />\n+  <Import Project="..\\..\\BuildFiles\\Microsoft.Portable.Core.targets" Condition="$(teamcity_build_id) != \'\'" />\n+  <Import Project="$(MSBuildExtensionsPath32)\\Microsoft\\Portable\\$(TargetFrameworkVersion)\\Microsoft.Portable.CSharp.targets" Condition="$(teamcity_build_id) == \'\'" />\n+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n+       Other similar extension points exist, see Microsoft.Common.targets.\n+  <Target Name="BeforeBuild">\n+  </Target>\n+  <Target Name="AfterBuild">\n+  </Target>\n+  -->\n+</Project>\n\\ No newline at end of file\ndiff --git a/Source/Grace.Validation/Impl/ValidationService.cs b/Source/Grace.Validation/Impl/ValidationService.cs\nnew file mode 100644\nindex 0000000..1c21a4c\n--- /dev/null\n+++ b/Source/Grace.Validation/Impl/ValidationService.cs\n@@ -0,0 +1,12 @@\n+\ufeffusing System;\n+using System.Collections.Generic;\n+using System.Linq;\n+using System.Text;\n+using System.Threading.Tasks;\n+\n+namespace Grace.Validation.Impl\n+{\n+\tpublic class ValidationService\n+\t{\n+\t}\n+}\ndiff --git a/Source/Grace.Validation/Properties/AssemblyInfo.cs b/Source/Grace.Validation/Properties/AssemblyInfo.cs\nnew file mode 100644\nindex 0000000..08dfc71\n--- /dev/null\n+++ b/Source/Grace.Validation/Properties/AssemblyInfo.cs\n@@ -0,0 +1,30 @@\n+\ufeffusing System.Resources;\n+using System.Reflection;\n+using System.Runtime.CompilerServices;\n+using System.Runtime.InteropServices;\n+\n+// General Information about an assembly is controlled through the following \n+// set of attributes. Change these attribute values to modify the information\n+// associated with an assembly.\n+[assembly: AssemblyTitle("Grace.Validation")]\n+[assembly: AssemblyDescription("")]\n+[assembly: AssemblyConfiguration("")]\n+[assembly: AssemblyCompany("")]\n+[assembly: AssemblyProduct("Grace.Validation")]\n+[assembly: AssemblyCopyright("Copyright ©  2014")]\n+[assembly: AssemblyTrademark("")]\n+[assembly: AssemblyCulture("")]\n+[assembly: NeutralResourcesLanguage("en")]\n+\n+// Version information for an assembly consists of the following four values:\n+//\n+//      Major Version\n+//      Minor Version \n+//      Build Number\n+//      Revision\n+//\n+// You can specify all the values or you can default the Build and Revision Numbers \n+// by using the \'*\' as shown below:\n+// [assembly: AssemblyVersion("1.0.*")]\n+[assembly: AssemblyVersion("1.0.0.0")]\n+[assembly: AssemblyFileVersion("1.0.0.0")]\ndiff --git a/Source/Grace.sln b/Source/Grace.sln\nindex ecdb80e..c3dff96 100644\n--- a/Source/Grace.sln\n+++ b/Source/Grace.sln\n@@ -1,8 +1,7 @@\n \ufeff\n Microsoft Visual Studio Solution File, Format Version 12.00\n # Visual Studio 2013\n-VisualStudioVersion = 12.0.30110.0\n-MinimumVisualStudioVersion = 10.0.40219.1\n+VisualStudioVersion = 12.0.30324.0\n Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grace", "Grace\\Grace.csproj", "{2E64FA60-F2CD-428C-8413-D71B4BF5935A}"\n EndProject\n Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grace.Net", "Grace.Net\\Grace.Net.csproj", "{C2FDC6DD-E8BA-4550-8C4E-97EDF9A01B95}"\n@@ -59,6 +58,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grace.Templates", "Grace.Te\n EndProject\n Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grace.Common.Logging", "Grace.Common.Logging\\Grace.Common.Logging.csproj", "{D6695499-1CA3-455B-970E-FB0D2DAA18C2}"\n EndProject\n+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grace.Validation", "Grace.Validation\\Grace.Validation.csproj", "{8D654B69-45DB-47C5-BB82-CE6D02670220}"\n+EndProject\n Global\n \tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n \t\tDebug|Any CPU = Debug|Any CPU\n@@ -117,20 +118,24 @@ Global\n \t\t{D6695499-1CA3-455B-970E-FB0D2DAA18C2}.Debug|Any CPU.Build.0 = Debug|Any CPU\n \t\t{D6695499-1CA3-455B-970E-FB0D2DAA18C2}.Release|Any CPU.ActiveCfg = Release|Any CPU\n \t\t{D6695499-1CA3-455B-970E-FB0D2DAA18C2}.Release|Any CPU.Build.0 = Release|Any CPU\n+\t\t{8D654B69-45DB-47C5-BB82-CE6D02670220}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n+\t\t{8D654B69-45DB-47C5-BB82-CE6D02670220}.Debug|Any CPU.Build.0 = Debug|Any CPU\n+\t\t{8D654B69-45DB-47C5-BB82-CE6D02670220}.Release|Any CPU.ActiveCfg = Release|Any CPU\n+\t\t{8D654B69-45DB-47C5-BB82-CE6D02670220}.Release|Any CPU.Build.0 = Release|Any CPU\n \tEndGlobalSection\n \tGlobalSection(SolutionProperties) = preSolution\n \t\tHideSolutionNode = FALSE\n \tEndGlobalSection\n \tGlobalSection(NestedProjects) = preSolution\n-\t\t{4EE2F531-4968-4910-83E4-DEFD58537BA8} = {D824794F-C32B-450C-8150-F54B4848B949}\n \t\t{742CB845-347E-42F2-9133-E8775E36F83C} = {D824794F-C32B-450C-8150-F54B4848B949}\n-\t\t{2ED7B534-6054-4AAE-858E-A6BC2B323CDB} = {D824794F-C32B-450C-8150-F54B4848B949}\n+\t\t{4EE2F531-4968-4910-83E4-DEFD58537BA8} = {D824794F-C32B-450C-8150-F54B4848B949}\n \t\t{1EB4796E-9FEA-42F3-A206-E44CF4DF6ED2} = {F6A98F7E-8C40-47C6-B04D-878908608023}\n-\t\t{F971978C-23BA-4B5C-B6BB-467B621D4D51} = {3A1809AF-15A1-498A-97F5-79AD09EC8F81}\n \t\t{C05F9C12-8915-4B43-9C83-9B63C8079936} = {3A1809AF-15A1-498A-97F5-79AD09EC8F81}\n+\t\t{F971978C-23BA-4B5C-B6BB-467B621D4D51} = {3A1809AF-15A1-498A-97F5-79AD09EC8F81}\n \t\t{EFED8FDA-9B2D-4353-8854-8FA2F767F2AB} = {F26376D4-77AC-4095-ACE8-9D17ADD1C543}\n+\t\t{2ED7B534-6054-4AAE-858E-A6BC2B323CDB} = {D824794F-C32B-450C-8150-F54B4848B949}\n \t\t{F83E7F91-BA18-4F06-A0BA-D2B86B2B10B0} = {F26376D4-77AC-4095-ACE8-9D17ADD1C543}\n-\t\t{D6695499-1CA3-455B-970E-FB0D2DAA18C2} = {F26376D4-77AC-4095-ACE8-9D17ADD1C543}\n \t\t{FA16AAB4-B28A-46B1-810C-876E333B1373} = {36C6B292-1625-491E-9807-DB189E2A3587}\n+\t\t{D6695499-1CA3-455B-970E-FB0D2DAA18C2} = {F26376D4-77AC-4095-ACE8-9D17ADD1C543}\n \tEndGlobalSection\n EndGlobal\ndiff --git a/Source/Grace/Data/IReflectionService.cs b/Source/Grace/Data/IReflectionService.cs\nindex a8369f5..c19d795 100644\n--- a/Source/Grace/Data/IReflectionService.cs\n+++ b/Source/Grace/Data/IReflectionService.cs\n@@ -20,6 +20,13 @@ namespace Grace.Data\n \t/// </summary>\n \tpublic interface IReflectionService\n \t{\n+\t\t/// <summary>\n+\t\t/// Gets a named property value from an object\n+\t\t/// </summary>\n+\t\t/// <param name="valueObject">target object</param>\n+\t\t/// <param name="propertyName">property name (can be nested A.B.C.D)</param>\n+\t\t/// <returns>property value</returns>\n+\t\tobject GetPropertyValue(object valueObject, string propertyName);\n \n \t\t/// <summary>\n \t\t/// Gets a named property value from an object\n@@ -31,8 +38,16 @@ namespace Grace.Data\n \t\t/// <returns>property value</returns>\n \t\tobject GetPropertyValue(object valueObject,\n \t\t\t\t\t\t\t\t\t\tstring propertyName,\n-\t\t\t\t\t\t\t\t\t\tobject index = null,\n-\t\t\t\t\t\t\t\t\t\tbool throwIfPathMissing = false);\n+\t\t\t\t\t\t\t\t\t\tobject index,\n+\t\t\t\t\t\t\t\t\t\tbool throwIfPathMissing);\n+\n+\t\t/// <summary>\n+\t\t/// Sets a value into a named Property\n+\t\t/// </summary>\n+\t\t/// <param name="valueObject">target object</param>\n+\t\t/// <param name="propertyName">property name to fetch</param>\n+\t\t/// <param name="newValue"></param>\n+\t\tbool SetPropertyValue(object valueObject, string propertyName, object newValue);\n \n \t\t/// <summary>\n \t\t/// Sets a value into a named Property\n@@ -45,8 +60,8 @@ namespace Grace.Data\n \t\tbool SetPropertyValue(object valueObject,\n \t\t\t\t\t\t\t\t\t string propertyName,\n \t\t\t\t\t\t\t\t\t object newValue,\n-\t\t\t\t\t\t\t\t\t object index = null,\n-\t\t\t\t\t\t\t\t\t bool createIfPathMissing = false);\n+\t\t\t\t\t\t\t\t\t object index,\n+\t\t\t\t\t\t\t\t\t bool createIfPathMissing);\n \n \t\t/// <summary>\n \t\t/// Calls a method in the target by a specified name.\ndiff --git a/Source/Grace/Data/ReflectionService.cs b/Source/Grace/Data/ReflectionService.cs\nindex 3988f25..3dd0e22 100644\n--- a/Source/Grace/Data/ReflectionService.cs\n+++ b/Source/Grace/Data/ReflectionService.cs\n@@ -1,12 +1,672 @@\n \ufeffusing System;\n+using System.Collections;\n using System.Collections.Generic;\n using System.Linq;\n+using System.Linq.Expressions;\n+using System.Reflection;\n+using System.Runtime.Serialization;\n using System.Text;\n using System.Threading.Tasks;\n+using Grace.Utilities;\n \n namespace Grace.Data\n {\n-\tclass ReflectionService\n+\t/// <summary>\n+\t/// Service creates delegates that can be used to access properties off objects at runtime\n+\t/// </summary>\n+\tpublic class ReflectionService : IReflectionService\n \t{\n+\t\tprivate static readonly ConstructorInfo exceptionConstructor = null;\n+\t\tprivate static readonly PropertyInfo objectArrayIndex = null;\n+\n+\t\tprivate readonly SafeDictionary<string, GetPropertyDelegate> getPropertyAccessors;\n+\t\tprivate readonly SafeDictionary<string, SetPropertyDelegate> setPropertyAccessors;\n+\t\tprivate readonly SafeDictionary<string, CallMethodDelegate> callAccessors;\n+\n+\t\tstatic ReflectionService()\n+\t\t{\n+\t\t\tobjectArrayIndex = typeof(IList).GetTypeInfo().GetDeclaredProperty("Item");\n+\n+\t\t\tforeach (ConstructorInfo declaredConstructor in typeof(Exception).GetTypeInfo().DeclaredConstructors)\n+\t\t\t{\n+\t\t\t\tif (declaredConstructor.GetParameters().Count() == 1 &&\n+\t\t\t\t\t declaredConstructor.GetParameters().FirstOrDefault().ParameterType == typeof(string))\n+\t\t\t\t{\n+\t\t\t\t\texceptionConstructor = declaredConstructor;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t}\n+\n+\t\t/// <summary>\n+\t\t/// Default constructor\n+\t\t/// </summary>\n+\t\tpublic ReflectionService()\n+\t\t{\n+\t\t\tgetPropertyAccessors =\n+\t\t\t\tnew SafeDictionary<string, GetPropertyDelegate>();\n+\n+\t\t\tsetPropertyAccessors =\n+\t\t\t\tnew SafeDictionary<string, SetPropertyDelegate>();\n+\n+\t\t\tcallAccessors =\n+\t\t\t\tnew SafeDictionary<string, CallMethodDelegate>();\n+\t\t}\n+\n+\t\t/// <summary>\n+\t\t/// Gets a named property value from an object\n+\t\t/// </summary>\n+\t\t/// <param name="valueObject">target object</param>\n+\t\t/// <param name="propertyName">property name (can be nested A.B.C.D)</param>\n+\t\t/// <returns>property value</returns>\n+\t\tpublic object GetPropertyValue(object valueObject, string propertyName)\n+\t\t{\n+\t\t\treturn GetPropertyValue(valueObject, propertyName, null, false);\n+\t\t}\n+\n+\t\t/// <summary>\n+\t\t/// Gets a named property value from an object\n+\t\t/// </summary>\n+\t\t/// <param name="valueObject">target object</param>\n+\t\t/// <param name="propertyName">property name (can be nested A.B.C.D)</param>\n+\t\t/// <param name="index">index for final property</param>\n+\t\t/// <param name="throwIfPathMissing">throw an exception if any part of the path is missing</param>\n+\t\t/// <returns>property value</returns>\n+\t\tpublic object GetPropertyValue(object valueObject, string propertyName, object index, bool throwIfPathMissing)\n+\t\t{\n+\t\t\tif (valueObject == null)\n+\t\t\t{\n+\t\t\t\tthrow new ArgumentNullException("valueObject");\n+\t\t\t}\n+\n+\t\t\tif (string.IsNullOrEmpty(propertyName))\n+\t\t\t{\n+\t\t\t\tthrow new ArgumentNullException("propertyName");\n+\t\t\t}\n+\n+\t\t\tType indexType = null;\n+\n+\t\t\tif (index != null)\n+\t\t\t{\n+\t\t\t\tindexType = index.GetType();\n+\t\t\t}\n+\n+\t\t\tGetPropertyDelegate getAction = CreateGetPropertyDelegate(valueObject.GetType(), propertyName, indexType);\n+\n+\t\t\tif (getAction != null)\n+\t\t\t{\n+\t\t\t\treturn getAction(valueObject, index, throwIfPathMissing);\n+\t\t\t}\n+\n+\t\t\tthrow new Exception("Could not create property delegate");\n+\t\t}\n+\n+\t\t/// <summary>\n+\t\t/// Sets a value into a named Property\n+\t\t/// </summary>\n+\t\t/// <param name="valueObject">target object</param>\n+\t\t/// <param name="propertyName">property name to fetch</param>\n+\t\t/// <param name="newValue"></param>\n+\t\tpublic bool SetPropertyValue(object valueObject, string propertyName, object newValue)\n+\t\t{\n+\t\t\treturn SetPropertyValue(valueObject, propertyName, newValue, null, true);\n+\t\t}\n+\n+\t\t/// <summary>\n+\t\t/// Sets a value into a named Property\n+\t\t/// </summary>\n+\t\t/// <param name="valueObject">target object</param>\n+\t\t/// <param name="propertyName">property name to fetch</param>\n+\t\t/// <param name="newValue"></param>\n+\t\t/// <param name="index"></param>\n+\t\t/// <param name="createIfPathMissing"></param>\n+\t\tpublic bool SetPropertyValue(object valueObject,\n+\t\t\t\t\t\t\t\t\t\t\t  string propertyName,\n+\t\t\t\t\t\t\t\t\t\t\t  object newValue,\n+\t\t\t\t\t\t\t\t\t\t\t  object index,\n+\t\t\t\t\t\t\t\t\t\t\t  bool createIfPathMissing)\n+\t\t{\n+\t\t\tif (valueObject == null)\n+\t\t\t{\n+\t\t\t\tthrow new ArgumentNullException("valueObject");\n+\t\t\t}\n+\n+\t\t\tif (string.IsNullOrEmpty(propertyName))\n+\t\t\t{\n+\t\t\t\tthrow new ArgumentNullException("propertyName");\n+\t\t\t}\n+\n+\t\t\tType indexType = null;\n+\n+\t\t\tif (index != null)\n+\t\t\t{\n+\t\t\t\tindexType = index.GetType();\n+\t\t\t}\n+\n+\t\t\tSetPropertyDelegate setAction = CreateSetPropertyDelegate(valueObject.GetType(), propertyName, indexType);\n+\n+\t\t\tif (setAction != null)\n+\t\t\t{\n+\t\t\t\tsetAction(valueObject, newValue, index, createIfPathMissing);\n+\n+\t\t\t\treturn true;\n+\t\t\t}\n+\n+\t\t\tthrow new Exception("Could not create set for property " + propertyName);\n+\t\t}\n+\n+\t\t/// <summary>\n+\t\t/// Calls a method in the target by a specified name.\n+\t\t/// For a method with a return type of void use T type of object\n+\t\t/// </summary>\n+\t\t/// <typeparam name="T">the return type of the method</typeparam>\n+\t\t/// <param name="target">the target object</param>\n+\t\t/// <param name="methodName">method name (can be dotted form A.B.C</param>\n+\t\t/// <param name="throwIfPathMissing">throw an exception if part of the path is missing</param>\n+\t\t/// <param name="parameters">parameters to the method</param>\n+\t\t/// <returns>the value the method returns</returns>\n+\t\tpublic object CallMethod(object target, string methodName, bool throwIfPathMissing, params object[] parameters)\n+\t\t{\n+\t\t\tif (target == null)\n+\t\t\t{\n+\t\t\t\tthrow new ArgumentNullException("target");\n+\t\t\t}\n+\n+\t\t\tif (string.IsNullOrEmpty(methodName))\n+\t\t\t{\n+\t\t\t\tthrow new ArgumentNullException("methodName");\n+\t\t\t}\n+\n+\t\t\tCallMethodDelegate callMethod = null;\n+\t\t\tstring searchMethodName = methodName;\n+\n+\t\t\tif (parameters != null && parameters.Length > 0)\n+\t\t\t{\n+\t\t\t\tsearchMethodName += "|" + parameters.Length;\n+\t\t\t}\n+\n+\t\t\tif (!callAccessors.TryGetValue(searchMethodName, out callMethod))\n+\t\t\t{\n+\t\t\t\tParameterExpression valueObjectParameter = Expression.Parameter(typeof(object), "valueObject");\n+\t\t\t\tParameterExpression callParameters = Expression.Parameter(typeof(object[]), "callParameters");\n+\t\t\t\tParameterExpression throwParameter = Expression.Parameter(typeof(bool), "throwIfMissing");\n+\t\t\t\tParameterExpression returnValue = Expression.Variable(typeof(object), "returnValue");\n+\n+\t\t\t\tParameterExpression castValue = Expression.Variable(target.GetType(), "castValue");\n+\t\t\t\tExpression castExpression =\n+\t\t\t\t\tExpression.Assign(castValue,\n+\t\t\t\t\t\t\t\t\t\t\tExpression.Convert(valueObjectParameter, target.GetType()));\n+\n+\t\t\t\tExpression accessBlock\n+\t\t\t\t\t= CreateAccessPathCode(castValue,\n+\t\t\t\t\t\t\t\t\t\t\t\t  throwParameter,\n+\t\t\t\t\t\t\t\t\t\t\t\t  target.GetType(),\n+\t\t\t\t\t\t\t\t\t\t\t\t  methodName,\n+\t\t\t\t\t\t\t\t\t\t\t\t  (type, name, expression) =>\n+\t\t\t\t\t\t\t\t\t\t\t\t  {\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  MethodInfo callMethodInfo = null;\n+\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  foreach (MethodInfo declaredMethod in\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t  type.GetTypeInfo().GetDeclaredMethods(name))\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  {\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t  if (parameters != null)\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t  {\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  if (declaredMethod.GetParameters().Length == parameters.Length)\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  {\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  callMethodInfo = declaredMethod;\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  break;\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  }\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t  }\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t  else if (declaredMethod.GetParameters().Length == 0)\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t  {\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  callMethodInfo = declaredMethod;\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  break;\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t  }\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  }\n+\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  if (callMethodInfo == null)\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  {\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t  throw new Exception(\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  string.Format("Could not find method {0} on {1}",\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t name,\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t type.FullName));\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  }\n+\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  Expression callExpression = null;\n+\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  if (parameters != null && parameters.Length > 0)\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  {\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t  int parmeterIndex = 0;\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t  List<Expression> callParametersList = new List<Expression>();\n+\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t  foreach (var parameterInfo in callMethodInfo.GetParameters())\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t  {\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  Expression callParameter =\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  Expression.Convert(\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  Expression.Property(callParameters,\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t objectArrayIndex,\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t Expression.Constant(parmeterIndex)),\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  parameterInfo.ParameterType);\n+\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  callParametersList.Add(callParameter);\n+\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  parmeterIndex++;\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t  }\n+\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t  callExpression =\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  Expression.Call(expression, callMethodInfo, callParametersList);\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  }\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  else\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  {\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t  callExpression =\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  Expression.Call(expression, callMethodInfo);\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  }\n+\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  if (callMethodInfo.ReturnType.Name == "Void")\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  {\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t  return callExpression;\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  }\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  else\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  {\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t  return Expression.Assign(\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  returnValue,\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  Expression.Convert(\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  callExpression,\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  typeof(object)));\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  }\n+\t\t\t\t\t\t\t\t\t\t\t\t  });\n+\n+\t\t\t\tBlockExpression delegatebod =\n+\t\t\t\t\tExpression.Block(new[] { castValue, returnValue },\n+\t\t\t\t\t\t\t\t\t\t  castExpression,\n+\t\t\t\t\t\t\t\t\t\t  accessBlock,\n+\t\t\t\t\t\t\t\t\t\t  returnValue);\n+\n+\t\t\t\tcallMethod = Expression.Lambda<CallMethodDelegate>(\n+\t\t\t\t\tdelegatebod, valueObjectParameter, throwParameter, callParameters).\n+\t\t\t\t\t\t\t\t\t\t\t\tCompile();\n+\n+\t\t\t\tcallAccessors[searchMethodName] = callMethod;\n+\t\t\t}\n+\n+\t\t\treturn callMethod(target, throwIfPathMissing, parameters);\n+\t\t}\n+\n+\t\t/// <summary>\n+\t\t/// Creates a new delegate that can be used to access a property in an object by property name\n+\t\t/// </summary>\n+\t\t/// <param name="instanceType">object type to target</param>\n+\t\t/// <param name="propertyName">property name (can be dotted form A.B.C)</param>\n+\t\t/// <returns>new property delegate</returns>\n+\t\tpublic GetPropertyDelegate CreateGetPropertyDelegate(Type instanceType, string propertyName, Type indexType)\n+\t\t{\n+\t\t\tGetPropertyDelegate getAction = null;\n+\t\t\tstring methodName = instanceType.FullName + "." + propertyName;\n+\n+\t\t\tif (indexType != null)\n+\t\t\t{\n+\t\t\t\tmethodName += "|" + indexType.FullName;\n+\t\t\t}\n+\n+\t\t\tif (!getPropertyAccessors.TryGetValue(methodName, out getAction))\n+\t\t\t{\n+\t\t\t\tParameterExpression valueObjectParameter = Expression.Parameter(typeof(object), "valueObject");\n+\t\t\t\tParameterExpression indexParameter = Expression.Parameter(typeof(object), "index");\n+\t\t\t\tParameterExpression throwParameter = Expression.Parameter(typeof(bool), "throwIfMissing");\n+\t\t\t\tParameterExpression returnValueExpression = Expression.Variable(typeof(object), "returnValue");\n+\n+\t\t\t\tParameterExpression castValue = Expression.Variable(instanceType, "castValue");\n+\t\t\t\tExpression castExpression =\n+\t\t\t\t\tExpression.Assign(castValue,\n+\t\t\t\t\t\t\t\t\t\t\tExpression.Convert(valueObjectParameter, instanceType));\n+\n+\t\t\t\tExpression accessBlock\n+\t\t\t\t\t= CreateAccessPathCode(castValue,\n+\t\t\t\t\t\t\t\t\t\t\t\t  throwParameter,\n+\t\t\t\t\t\t\t\t\t\t\t\t  instanceType,\n+\t\t\t\t\t\t\t\t\t\t\t\t  propertyName,\n+\t\t\t\t\t\t\t\t\t\t\t\t  (type, name, expression) =>\n+\t\t\t\t\t\t\t\t\t\t\t\t  {\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  Expression returnValue = null;\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  Type fieldOrPropertyType = CreateGetPropertyOrFieldType(type, name);\n+\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  if (indexType != null)\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  {\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t  PropertyInfo propertyInfo =\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  type.GetTypeInfo().GetDeclaredProperty(propertyName);\n+\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t  if (propertyInfo != null)\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t  {\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  returnValue = Expression.Assign(\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  returnValueExpression,\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  Expression.Convert(\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  Expression.Property(expression,\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t propertyInfo,\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t Expression.Convert(indexParameter, indexType)),\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  typeof(object)));\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t  }\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t  else\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t  {\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  throw new Exception(\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  string.Format("Could not find property {0} on type {1}",\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t type.FullName,\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t name));\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t  }\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  }\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  else\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  {\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t  returnValue = Expression.Assign(\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  returnValueExpression,\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  Expression.Convert(\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  Expression.PropertyOrField(expression, name), typeof(object)));\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  }\n+\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  return returnValue;\n+\t\t\t\t\t\t\t\t\t\t\t\t  });\n+\n+\t\t\t\tBlockExpression returnBlock =\n+\t\t\t\t\tExpression.Block(new[] { castValue, returnValueExpression },\n+\t\t\t\t\t\t\t\t\t\t  castExpression,\n+\t\t\t\t\t\t\t\t\t\t  accessBlock,\n+\t\t\t\t\t\t\t\t\t\t  returnValueExpression);\n+\n+\t\t\t\tgetAction = Expression.Lambda<GetPropertyDelegate>(\n+\t\t\t\t\treturnBlock, valueObjectParameter, indexParameter, throwParameter).\n+\t\t\t\t\t\t\t\t\t\t\t  Compile();\n+\n+\t\t\t\tgetPropertyAccessors[methodName] = getAction;\n+\t\t\t}\n+\n+\t\t\treturn getAction;\n+\t\t}\n+\n+\t\t/// <summary>\n+\t\t/// Creates a new delegate that be used to set a property on an object by property name\n+\t\t/// </summary>\n+\t\t/// <param name="instanceType">object type to target</param>\n+\t\t/// <param name="propertyName">property name (can be dotted form A.B.C)</param>\n+\t\t/// <param name="indexType">type of property used for indexing</param>\n+\t\t/// <returns>new property delegate</returns>\n+\t\tpublic SetPropertyDelegate CreateSetPropertyDelegate(Type instanceType, string propertyName, Type indexType)\n+\t\t{\n+\t\t\tif (instanceType == null)\n+\t\t\t{\n+\t\t\t\tthrow new ArgumentNullException("instanceType");\n+\t\t\t}\n+\n+\t\t\tif (string.IsNullOrEmpty(propertyName))\n+\t\t\t{\n+\t\t\t\tthrow new ArgumentNullException("propertyName");\n+\t\t\t}\n+\n+\t\t\tSetPropertyDelegate setAction = null;\n+\t\t\tstring methodName = instanceType.FullName + "." + propertyName;\n+\n+\t\t\tif (indexType != null)\n+\t\t\t{\n+\t\t\t\tmethodName += "|" + indexType.FullName;\n+\t\t\t}\n+\n+\t\t\tif (!setPropertyAccessors.TryGetValue(methodName, out setAction))\n+\t\t\t{\n+\t\t\t\tParameterExpression valueObjectParameter = Expression.Parameter(typeof(object), "valueObject");\n+\t\t\t\tParameterExpression newValueParameter = Expression.Parameter(typeof(object), "newValueParameter");\n+\t\t\t\tParameterExpression indexParameter = Expression.Parameter(typeof(object), "index");\n+\t\t\t\tParameterExpression createParameter = Expression.Parameter(typeof(bool), "createIfMissing");\n+\n+\t\t\t\tParameterExpression castValue = Expression.Variable(instanceType, "castValue");\n+\t\t\t\tExpression castExpression =\n+\t\t\t\t\tExpression.Assign(castValue,\n+\t\t\t\t\t\t\t\t\t\t\tExpression.Convert(valueObjectParameter, instanceType));\n+\n+\t\t\t\tExpression accessBlock\n+\t\t\t\t\t= CreateAccessPathCode(castValue,\n+\t\t\t\t\t\t\t\t\t\t\t\t  createParameter,\n+\t\t\t\t\t\t\t\t\t\t\t\t  instanceType,\n+\t\t\t\t\t\t\t\t\t\t\t\t  propertyName,\n+\t\t\t\t\t\t\t\t\t\t\t\t  (type, name, expression) =>\n+\t\t\t\t\t\t\t\t\t\t\t\t  {\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  Expression returnValue = null;\n+\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  if (indexType != null)\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  {\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t  PropertyInfo propertyInfo =\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  type.GetTypeInfo().GetDeclaredProperty(propertyName);\n+\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t  if (propertyInfo != null)\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t  {\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  returnValue = Expression.Assign(\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  Expression.Property(expression,\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t propertyInfo,\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t Expression.Convert(indexParameter, indexType)),\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  Expression.Convert(newValueParameter, propertyInfo.PropertyType));\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t  }\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t  else\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t  {\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  throw new Exception(\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  string.Format("Could not find property {0} on type {1}",\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t type.FullName,\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t name));\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t  }\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  }\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  else\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  {\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t  Type fieldOrPropertyType = CreateGetPropertyOrFieldType(type, name);\n+\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t  returnValue = Expression.Assign(\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  Expression.PropertyOrField(expression, name),\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  Expression.Convert(newValueParameter, fieldOrPropertyType));\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  }\n+\n+\t\t\t\t\t\t\t\t\t\t\t\t\t  return returnValue;\n+\t\t\t\t\t\t\t\t\t\t\t\t  });\n+\n+\t\t\t\tBlockExpression delegatebod =\n+\t\t\t\t\tExpression.Block(new[] { castValue }, castExpression, accessBlock);\n+\n+\t\t\t\tsetAction = Expression.Lambda<SetPropertyDelegate>(\n+\t\t\t\t\tdelegatebod, valueObjectParameter, newValueParameter, indexParameter, createParameter).\n+\t\t\t\t\t\t\t\t\t\t\t  Compile();\n+\n+\t\t\t\tsetPropertyAccessors[methodName] = setAction;\n+\t\t\t}\n+\n+\t\t\treturn setAction;\n+\t\t}\n+\n+\t\t/// <summary>\n+\t\t/// Gets property info for a dotted property\n+\t\t/// </summary>\n+\t\t/// <param name="baseType">type</param>\n+\t\t/// <param name="propertyString">property string</param>\n+\t\t/// <returns></returns>\n+\t\tpublic static PropertyInfo GetPropertyInfo(Type baseType, string propertyString)\n+\t\t{\n+\t\t\tif (baseType == null)\n+\t\t\t{\n+\t\t\t\tthrow new ArgumentNullException("baseType");\n+\t\t\t}\n+\n+\t\t\tif (string.IsNullOrEmpty(propertyString))\n+\t\t\t{\n+\t\t\t\tthrow new ArgumentNullException("propertyString");\n+\t\t\t}\n+\n+\t\t\tint periodIndex = propertyString.IndexOf(\'.\');\n+\n+\t\t\tif (periodIndex > 0)\n+\t\t\t{\n+\t\t\t\tstring newPropertyString = propertyString.Substring(0, periodIndex);\n+\t\t\t\tstring theRest = propertyString.Substring(periodIndex + 1);\n+\n+\t\t\t\tPropertyInfo propertyInfo =\n+\t\t\t\t\tbaseType.GetTypeInfo().GetDeclaredProperty(newPropertyString);\n+\n+\t\t\t\tif (propertyInfo != null)\n+\t\t\t\t{\n+\t\t\t\t\treturn GetPropertyInfo(propertyInfo.PropertyType, theRest);\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\telse\n+\t\t\t{\n+\t\t\t\tPropertyInfo propertyInfo =\n+\t\t\t\t\tbaseType.GetTypeInfo().GetDeclaredProperty(propertyString);\n+\n+\t\t\t\tif (propertyInfo != null)\n+\t\t\t\t{\n+\t\t\t\t\treturn propertyInfo;\n+\t\t\t\t}\n+\t\t\t}\n+\n+\t\t\treturn null;\n+\t\t}\n+\n+\t\tinternal static string GetPropertyAccessPath(Expression<Func<object, object>> method)\n+\t\t{\n+\t\t\tif (method == null)\n+\t\t\t{\n+\t\t\t\tthrow new ArgumentNullException("method");\n+\t\t\t}\n+\n+\t\t\tMemberExpression memberExpr = null;\n+\n+\t\t\tif (method.Body.NodeType == ExpressionType.Convert)\n+\t\t\t{\n+\t\t\t\tmemberExpr =\n+\t\t\t\t\t((UnaryExpression)method.Body).Operand as MemberExpression;\n+\t\t\t}\n+\t\t\telse if (method.Body.NodeType == ExpressionType.MemberAccess)\n+\t\t\t{\n+\t\t\t\tmemberExpr = method.Body as MemberExpression;\n+\t\t\t}\n+\n+\t\t\tif (memberExpr == null)\n+\t\t\t{\n+\t\t\t\tthrow new ArgumentException("method");\n+\t\t\t}\n+\n+\t\t\tStringBuilder builder = new StringBuilder();\n+\n+\t\t\twhile (memberExpr != null)\n+\t\t\t{\n+\t\t\t\tif (builder.Length != 0)\n+\t\t\t\t{\n+\t\t\t\t\tbuilder.Insert(0, \'.\');\n+\t\t\t\t}\n+\n+\t\t\t\tbuilder.Insert(0, memberExpr.Member.Name);\n+\n+\t\t\t\tmemberExpr = memberExpr.Expression as MemberExpression;\n+\t\t\t}\n+\n+\t\t\treturn builder.ToString();\n+\t\t}\n+\n+\t\tpublic static object ExternalCreateAccessPathCode(object valueParameter,\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  object throwParameter,\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  Type objectType,\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  string propertyName,\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  object createAction)\n+\t\t{\n+\t\t\treturn CreateAccessPathCode(valueParameter as ParameterExpression,\n+\t\t\t\t\t\t\t\t\t\t\t\t throwParameter as ParameterExpression,\n+\t\t\t\t\t\t\t\t\t\t\t\t objectType,\n+\t\t\t\t\t\t\t\t\t\t\t\t propertyName,\n+\t\t\t\t\t\t\t\t\t\t\t\t createAction as Func<Type, string, Expression, Expression>);\n+\t\t}\n+\n+\t\tprivate static Expression CreateAccessPathCode(ParameterExpression valueParameter,\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  ParameterExpression throwParameter,\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  Type objectType,\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  string propertyName,\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  Func<Type, string, Expression, Expression> createAction)\n+\t\t{\n+\t\t\tExpression returnExpression = null;\n+\t\t\tint firstPeriod = propertyName.IndexOf(\'.\');\n+\n+\t\t\tif (firstPeriod > 0)\n+\t\t\t{\n+\t\t\t\tstring currentPropertyName = propertyName.Substring(0, firstPeriod);\n+\t\t\t\tstring theRest = propertyName.Substring(firstPeriod + 1);\n+\t\t\t\tType propertyOrFieldType = CreateGetPropertyOrFieldType(objectType, currentPropertyName);\n+\n+\t\t\t\tParameterExpression newValue = Expression.Variable(propertyOrFieldType);\n+\n+\t\t\t\tExpression assignExpression = Expression.Assign(newValue,\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tExpression.PropertyOrField(valueParameter, currentPropertyName));\n+\n+\t\t\t\tif (!propertyOrFieldType.GetTypeInfo().IsValueType)\n+\t\t\t\t{\n+\t\t\t\t\tExpression recurse =\n+\t\t\t\t\t\tCreateAccessPathCode(newValue,\n+\t\t\t\t\t\t\t\t\t\t\t\t\tthrowParameter,\n+\t\t\t\t\t\t\t\t\t\t\t\t\tpropertyOrFieldType,\n+\t\t\t\t\t\t\t\t\t\t\t\t\ttheRest,\n+\t\t\t\t\t\t\t\t\t\t\t\t\tcreateAction);\n+\n+\t\t\t\t\tExpression ifExpression = Expression.IfThenElse(\n+\t\t\t\t\t\tExpression.NotEqual(newValue, Expression.Constant(null)),\n+\t\t\t\t\t\trecurse,\n+\t\t\t\t\t\tExpression.IfThen(Expression.IsTrue(throwParameter),\n+\t\t\t\t\t\t\t\t\t\t\t\tExpression.Throw(\n+\t\t\t\t\t\t\t\t\t\t\t\t\tExpression.New(\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\texceptionConstructor,\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\tExpression.Constant(\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tstring.Format("Could not find property {1} on type {0}",\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  objectType.FullName,\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  currentPropertyName))))));\n+\n+\t\t\t\t\treturnExpression =\n+\t\t\t\t\t\tExpression.Block(new[] { newValue }, new[] { assignExpression, ifExpression });\n+\t\t\t\t}\n+\t\t\t\telse\n+\t\t\t\t{\n+\t\t\t\t\tExpression recurse = CreateAccessPathCode(newValue,\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tthrowParameter,\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tpropertyOrFieldType,\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttheRest,\n+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tcreateAction);\n+\n+\t\t\t\t\treturnExpression =\n+\t\t\t\t\t\tExpression.Block(new[] { newValue }, new[] { assignExpression, recurse });\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\telse\n+\t\t\t{\n+\t\t\t\treturnExpression = createAction(objectType, propertyName, valueParameter);\n+\t\t\t}\n+\n+\t\t\treturn returnExpression;\n+\t\t}\n+\n+\t\tprivate static Type CreateGetPropertyOrFieldType(Type objectType, string propertyName)\n+\t\t{\n+\t\t\tType propertyOrFieldType = null;\n+\n+\t\t\tPropertyInfo propertyInfo =\n+\t\t\t\tobjectType.GetTypeInfo().GetDeclaredProperty(propertyName);\n+\n+\t\t\tif (propertyInfo == null)\n+\t\t\t{\n+\t\t\t\tFieldInfo field = objectType.GetTypeInfo().GetDeclaredField(propertyName);\n+\n+\t\t\t\tif (field != null)\n+\t\t\t\t{\n+\t\t\t\t\tpropertyOrFieldType = field.FieldType;\n+\t\t\t\t}\n+\t\t\t\telse\n+\t\t\t\t{\n+\t\t\t\t\tthrow new Exception(\n+\t\t\t\t\t\tstring.Format("Could not find property {0} on type {1}",\n+\t\t\t\t\t\t\t\t\t\t  objectType.FullName,\n+\t\t\t\t\t\t\t\t\t\t  propertyName));\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\telse\n+\t\t\t{\n+\t\t\t\tpropertyOrFieldType = propertyInfo.PropertyType;\n+\t\t\t}\n+\n+\t\t\treturn propertyOrFieldType;\n+\t\t}\n \t}\n }\ndiff --git a/Source/Grace/Grace.csproj b/Source/Grace/Grace.csproj\nindex 3fd88bd..e0eec7d 100644\n--- a/Source/Grace/Grace.csproj\n+++ b/Source/Grace/Grace.csproj\n@@ -45,7 +45,9 @@\n     <Compile Include="Data\\IComplexObject.cs" />\n     <Compile Include="Data\\IComplexObjectExtensions.cs" />\n     <Compile Include="Data\\IExtraDataContainer.cs" />\n+    <Compile Include="Data\\IReflectionService.cs" />\n     <Compile Include="Data\\NotifyObject.cs" />\n+    <Compile Include="Data\\ReflectionService.cs" />\n     <Compile Include="DependencyInjection\\Attributes\\ActivationCompleteAttribute.cs" />\n     <Compile Include="DependencyInjection\\Attributes\\ExportAttribute.cs" />\n     <Compile Include="DependencyInjection\\Attributes\\ExportByInterfacesAttribute.cs" />\n@@ -245,10 +247,22 @@\n     <Compile Include="Utilities\\TaskHelper.cs" />\n     <Compile Include="Utilities\\WeakAction.cs" />\n     <Compile Include="Utilities\\WeakFunc.cs" />\n+    <Compile Include="Validation\\IAsyncValidationRule.cs" />\n+    <Compile Include="Validation\\IAttributeValidationRuleProvider.cs" />\n+    <Compile Include="Validation\\IRuleExecutionContext.cs" />\n+    <Compile Include="Validation\\ISyncValidationRule.cs" />\n+    <Compile Include="Validation\\IValidationContext.cs" />\n+    <Compile Include="Validation\\IValidationRule.cs" />\n+    <Compile Include="Validation\\IValidationRuleProvider.cs" />\n+    <Compile Include="Validation\\IValidationRuleResult.cs" />\n+    <Compile Include="Validation\\IValidationRuleResultPart.cs" />\n+    <Compile Include="Validation\\IValidationService.cs" />\n+    <Compile Include="Validation\\IValidationStandardsSelector.cs" />\n+    <Compile Include="Validation\\IValidationStateChangedHandler.cs" />\n+    <Compile Include="Validation\\ValidationState.cs" />\n   </ItemGroup>\n   <ItemGroup>\n     <Folder Include="Configuration\\" />\n-    <Folder Include="Validation\\" />\n   </ItemGroup>\n   <Import Project="..\\..\\BuildFiles\\Microsoft.Portable.Core.props" Condition="$(teamcity_build_id) != \'\'" />\n   <Import Project="$(MSBuildToolsPath)\\Microsoft.CSharp.Targets" Condition="$(teamcity_build_id) != \'\'" />\ndiff --git a/Source/Grace/Validation/IAsyncValidationRule.cs b/Source/Grace/Validation/IAsyncValidationRule.cs\nnew file mode 100644\nindex 0000000..240073a\n--- /dev/null\n+++ b/Source/Grace/Validation/IAsyncValidationRule.cs\n@@ -0,0 +1,21 @@\n+\ufeffusing System;\n+using System.Collections.Generic;\n+using System.Linq;\n+using System.Text;\n+using System.Threading.Tasks;\n+\n+namespace Grace.Validation\n+{\n+\t/// <summary>\n+\t/// asynchronous validation rule\n+\t/// </summary>\n+\tpublic interface IAsyncValidationRule : IValidationRule\n+\t{\n+\t\t/// <summary>\n+\t\t/// Validate an object asynchronous\n+\t\t/// </summary>\n+\t\t/// <param name="ruleExecutionContext">execution context</param>\n+\t\t/// <returns>task</returns>\n+\t\tTask Validate(IRuleExecutionContext ruleExecutionContext);\n+\t}\n+}\ndiff --git a/Source/Grace/Validation/IAttributeValidationRuleProvider.cs b/Source/Grace/Validation/IAttributeValidationRuleProvider.cs\nnew file mode 100644\nindex 0000000..ec9de6d\n--- /dev/null\n+++ b/Source/Grace/Validation/IAttributeValidationRuleProvider.cs\n@@ -0,0 +1,25 @@\n+\ufeffusing System;\n+using System.Collections.Generic;\n+using System.Linq;\n+using System.Reflection;\n+using System.Text;\n+using System.Threading.Tasks;\n+\n+namespace Grace.Validation\n+{\n+\t/// <summary>\n+\t/// Provides validations rules based on the type and attributes provided\n+\t/// </summary>\n+\tpublic interface IAttributeValidationRuleProvider\n+\t{\n+\t\t/// <summary>\n+\t\t/// Provide an enumeration of validation rules based on the attributes on a type\n+\t\t/// </summary>\n+\t\t/// <param name="objectType">type being validated</param>\n+\t\t/// <param name="typeAttributes">attributes on the type</param>\n+\t\t/// <param name="propertyInfo">property info that is tagged, can be null when the attribute is on the type</param>\n+\t\t/// <param name="propertyInfoAttributes">attributes on the property, can be null</param>\n+\t\t/// <returns>list of validation rules</returns>\n+\t\tIEnumerable<IValidationRule> ProvideRules(Type objectType, IEnumerable<Attribute> typeAttributes, PropertyInfo propertyInfo, IEnumerable<Attribute> propertyInfoAttributes);\n+\t}\n+}\ndiff --git a/Source/Grace/Validation/IRuleExecutionContext.cs b/Source/Grace/Validation/IRuleExecutionContext.cs\nnew file mode 100644\nindex 0000000..7386339\n--- /dev/null\n+++ b/Source/Grace/Validation/IRuleExecutionContext.cs\n@@ -0,0 +1,91 @@\n+\ufeffusing System;\n+using System.Collections.Generic;\n+using System.Linq;\n+using System.Text;\n+using System.Threading.Tasks;\n+\n+namespace Grace.Validation\n+{\n+\t/// <summary>\n+\t/// Non Generic rule execution context\n+\t/// </summary>\n+\tpublic interface IRuleExecutionContext\n+\t{\n+\t\t/// <summary>\n+\t\t/// Validation state for rule execution\n+\t\t/// </summary>\n+\t\tValidationState State { get; set; }\n+\n+\t\t/// <summary>\n+\t\t/// Validation message\n+\t\t/// </summary>\n+\t\tstring Message { get; set; }\n+\n+\t\t/// <summary>\n+\t\t/// Object being validated\n+\t\t/// </summary>\n+\t\tobject ValidationObject { get; }\n+\n+\t\t/// <summary>\n+\t\t/// Add a validation part to the rule\n+\t\t/// </summary>\n+\t\t/// <param name="part">validation part</param>\n+\t\tvoid AddValidationPart(IValidationRuleResultPart part);\n+\n+\t\t/// <summary>\n+\t\t/// Adds required message\n+\t\t/// </summary>\n+\t\t/// <param name="partName">part that is required</param>\n+\t\t/// <param name="message">required message</param>\n+\t\tvoid AddRequired(string partName, string message);\n+\n+\t\t/// <summary>\n+\t\t/// Adds an error message to the context\n+\t\t/// </summary>\n+\t\t/// <param name="partName">part name that is invalid</param>\n+\t\t/// <param name="message">error message</param>\n+\t\tvoid AddError(string partName, string message);\n+\n+\n+\t\t/// <summary>\n+\t\t/// Add a warning message\n+\t\t/// </summary>\n+\t\t/// <param name="partName">part name that has warning</param>\n+\t\t/// <param name="message">warning message</param>\n+\t\tvoid AddWarning(string partName, string message);\n+\t}\n+\n+\t/// <summary>\n+\t/// Hold the information for rule execution\n+\t/// </summary>\n+\t/// <typeparam name="T"></typeparam>\n+\tpublic interface IRuleExecutionContext<out T>\n+\t{\n+\t\t/// <summary>\n+\t\t/// Current state\n+\t\t/// </summary>\n+\t\tValidationState State { get; set; }\n+\n+\t\t/// <summary>\n+\t\t/// Message for rule\n+\t\t/// </summary>\n+\t\tstring Message { get; set; }\n+\n+\t\t/// <summary>\n+\t\t/// Object to validate\n+\t\t/// </summary>\n+\t\tT ValidationObject { get; }\n+\n+\t\t/// <summary>\n+\t\t/// \n+\t\t/// </summary>\n+\t\t/// <param name="part"></param>\n+\t\tvoid AddValidationPart(IValidationRuleResultPart part);\n+\n+\t\tvoid AddRequired(string partName, string message);\n+\n+\t\tvoid AddError(string partName, string message);\n+\n+\t\tvoid AddWarning(string partName, string message);\n+\t}\n+}\ndiff --git a/Source/Grace/Validation/ISyncValidationRule.cs b/Source/Grace/Validation/ISyncValidationRule.cs\nnew file mode 100644\nindex 0000000..2429e78\n--- /dev/null\n+++ b/Source/Grace/Validation/ISyncValidationRule.cs\n@@ -0,0 +1,20 @@\n+\ufeffusing System;\n+using System.Collections.Generic;\n+using System.Linq;\n+using System.Text;\n+using System.Threading.Tasks;\n+\n+namespace Grace.Validation\n+{\n+\t/// <summary>\n+\t/// Represents a standard validation rule that runs synchronously \n+\t/// </summary>\n+\tpublic interface ISyncValidationRule : IValidationRule\n+\t{\n+\t\t/// <summary>\n+\t\t/// Validate an object\n+\t\t/// </summary>\n+\t\t/// <param name="ruleExecutionContext">rule execution context</param>\n+\t\tvoid Validate(IRuleExecutionContext ruleExecutionContext);\n+\t}\n+}\ndiff --git a/Source/Grace/Validation/IValidationContext.cs b/Source/Grace/Validation/IValidationContext.cs\nnew file mode 100644\nindex 0000000..17be2e3\n--- /dev/null\n+++ b/Source/Grace/Validation/IValidationContext.cs\n@@ -0,0 +1,12 @@\n+\ufeffusing System;\n+using System.Collections.Generic;\n+using System.Linq;\n+using System.Text;\n+using System.Threading.Tasks;\n+\n+namespace Grace.Validation\n+{\n+\tpublic interface IValidationContext\n+\t{\n+\t}\n+}\ndiff --git a/Source/Grace/Validation/IValidationRule.cs b/Source/Grace/Validation/IValidationRule.cs\nnew file mode 100644\nindex 0000000..b68c747\n--- /dev/null\n+++ b/Source/Grace/Validation/IValidationRule.cs\n@@ -0,0 +1,41 @@\n+\ufeffusing System;\n+using System.Collections.Generic;\n+using System.Linq;\n+using System.Text;\n+using System.Threading.Tasks;\n+\n+namespace Grace.Validation\n+{\n+\t/// <summary>\n+\t/// Represents a validation rule\n+\t/// </summary>\n+\tpublic interface IValidationRule\n+\t{\n+\t\t/// <summary>\n+\t\t/// Namespace the rule exists in\n+\t\t/// </summary>\n+\t\tstring Namespace { get; }\n+\n+\t\t/// <summary>\n+\t\t/// Display name for the rule\n+\t\t/// </summary>\n+\t\tstring DisplayName { get; }\n+\n+\t\t/// <summary>\n+\t\t/// Name for the rule\n+\t\t/// </summary>\n+\t\tstring Name { get; }\n+\n+\t\t/// <summary>\n+\t\t/// Properties this rule depends on\n+\t\t/// </summary>\n+\t\t/// <returns></returns>\n+\t\tIEnumerable<string> DependentProperties();\n+\n+\t\t/// <summary>\n+\t\t/// Standards this rule is a part of\n+\t\t/// </summary>\n+\t\t/// <returns></returns>\n+\t\tIEnumerable<string> Standards();\n+\t}\n+}\ndiff --git a/Source/Grace/Validation/IValidationRuleProvider.cs b/Source/Grace/Validation/IValidationRuleProvider.cs\nnew file mode 100644\nindex 0000000..c1705dc\n--- /dev/null\n+++ b/Source/Grace/Validation/IValidationRuleProvider.cs\n@@ -0,0 +1,24 @@\n+\ufeffusing System;\n+using System.Collections.Generic;\n+using System.Linq;\n+using System.Text;\n+using System.Threading.Tasks;\n+\n+namespace Grace.Validation\n+{\n+\t/// <summary>\n+\t/// classes thar implement this interface can provide validation rules for a type\n+\t/// </summary>\n+\tpublic interface IValidationRuleProvider\n+\t{\n+\t\t/// <summary>\n+\t\t/// \n+\t\t/// </summary>\n+\t\t/// <param name="objectType"></param>\n+\t\t/// <param name="standards"></param>\n+\t\t/// <returns></returns>\n+\t\tIEnumerable<IValidationRule> ProvideRules(Type objectType, IEnumerable<string> standards);\n+\n+\t\tIEnumerable<string> GetPropertiesToValidate(Type objectType, IEnumerable<string> standards);\n+\t}\n+}\ndiff --git a/Source/Grace/Validation/IValidationRuleResult.cs b/Source/Grace/Validation/IValidationRuleResult.cs\nnew file mode 100644\nindex 0000000..aafb8bf\n--- /dev/null\n+++ b/Source/Grace/Validation/IValidationRuleResult.cs\n@@ -0,0 +1,63 @@\n+\ufeffusing System;\n+using System.Collections.Generic;\n+using System.Linq;\n+using System.Text;\n+using System.Threading.Tasks;\n+\n+namespace Grace.Validation\n+{\n+\tpublic static class IValidationRuleResultExtensions\n+\t{\n+\t\tpublic static string FullRuleName(this IValidationRuleResult ruleResult)\n+\t\t{\n+\t\t\treturn ruleResult.Namespace + "." + ruleResult.RuleName;\n+\t\t}\n+\t}\n+\n+\t/// <summary>\n+\t/// Validation result for rule\n+\t/// </summary>\n+\tpublic interface IValidationRuleResult\n+\t{\n+\t\t/// <summary>\n+\t\t/// Namspace the rule exists in\n+\t\t/// </summary>\n+\t\tstring Namespace { get; }\n+\n+\t\t/// <summary>\n+\t\t/// Rule name\n+\t\t/// </summary>\n+\t\tstring RuleName { get; }\n+\n+\t\t/// <summary>\n+\t\t/// Object being validated\n+\t\t/// </summary>\n+\t\tobject ValidationObject { get; }\n+\n+\t\t/// <summary>\n+\t\t/// Rule display name\n+\t\t/// </summary>\n+\t\tstring DisplayName { get; }\n+\n+\t\t/// <summary>\n+\t\t/// Validation state\n+\t\t/// </summary>\n+\t\tValidationState State { get; }\n+\n+\t\t/// <summary>\n+\t\t/// Validation message\n+\t\t/// </summary>\n+\t\tstring Message { get; }\n+\n+\t\t/// <summary>\n+\t\t/// Root property path\n+\t\t/// </summary>\n+\t\tstring RootPropertyPath { get; set; }\n+\n+\t\t/// <summary>\n+\t\t/// Validation rule parts\n+\t\t/// </summary>\n+\t\t/// <returns></returns>\n+\t\tIEnumerable<IValidationRuleResultPart> ResultParts();\n+\t}\n+}\ndiff --git a/Source/Grace/Validation/IValidationRuleResultPart.cs b/Source/Grace/Validation/IValidationRuleResultPart.cs\nnew file mode 100644\nindex 0000000..7882aa1\n--- /dev/null\n+++ b/Source/Grace/Validation/IValidationRuleResultPart.cs\n@@ -0,0 +1,19 @@\n+\ufeffusing System;\n+using System.Collections.Generic;\n+using System.Linq;\n+using System.Text;\n+using System.Threading.Tasks;\n+\n+namespace Grace.Validation\n+{\n+\tpublic interface IValidationRuleResultPart\n+\t{\n+\t\tIValidationRuleResult RuleResult { get; }\n+\n+\t\tstring PartName { get; }\n+\n+\t\tValidationState State { get; }\n+\n+\t\tstring Message { get; }\n+\t}\n+}\ndiff --git a/Source/Grace/Validation/IValidationService.cs b/Source/Grace/Validation/IValidationService.cs\nnew file mode 100644\nindex 0000000..a6df9a3\n--- /dev/null\n+++ b/Source/Grace/Validation/IValidationService.cs\n@@ -0,0 +1,21 @@\n+\ufeffusing System;\n+using System.Collections.Generic;\n+using System.Linq;\n+using System.Text;\n+using System.Threading.Tasks;\n+\n+namespace Grace.Validation\n+{\n+\tpublic interface IValidationService\n+\t{\n+\t\tIValidationContext GetValidationContext(object validationObject);\n+\n+\t\tIValidationContext GetValidationContext(object validationObject, bool monitor);\n+\n+\t\tIValidationContext GetValidationContext(object validationObject, bool monitor, bool shared);\n+\n+\t\tIEnumerable<IValidationRule> FetchValidationRules(Type validationType, params string[] standards);\n+\n+\t\tIEnumerable<string> FetchPropertiesToValidate(Type validationType, params string[] standards);\n+\t}\n+}\ndiff --git a/Source/Grace/Validation/IValidationStandardsSelector.cs b/Source/Grace/Validation/IValidationStandardsSelector.cs\nnew file mode 100644\nindex 0000000..808d560\n--- /dev/null\n+++ b/Source/Grace/Validation/IValidationStandardsSelector.cs\n@@ -0,0 +1,19 @@\n+\ufeffusing System;\n+using System.Collections.Generic;\n+using System.Linq;\n+using System.Text;\n+using System.Threading.Tasks;\n+\n+namespace Grace.Validation\n+{\n+\tpublic interface IValidationStandardsSelector\n+\t{\n+\t\tType ValidationType();\n+\n+\t\tIEnumerable<string> Select(object validationObject);\n+\n+\t\tIEnumerable<string> MonitorProperties();\n+\n+\t\tevent EventHandler<string> StandardsChanged;\n+\t}\n+}\ndiff --git a/Source/Grace/Validation/IValidationStateChangedHandler.cs b/Source/Grace/Validation/IValidationStateChangedHandler.cs\nnew file mode 100644\nindex 0000000..be47908\n--- /dev/null\n+++ b/Source/Grace/Validation/IValidationStateChangedHandler.cs\n@@ -0,0 +1,13 @@\n+\ufeffusing System;\n+using System.Collections.Generic;\n+using System.Linq;\n+using System.Text;\n+using System.Threading.Tasks;\n+\n+namespace Grace.Validation\n+{\n+\tpublic interface IValidationStateChangedHandler\n+\t{\n+\t\tvoid StateChanged(IValidationContext context, ValidationState validationState);\n+\t}\n+}\ndiff --git a/Source/Grace/Validation/ValidationState.cs b/Source/Grace/Validation/ValidationState.cs\nnew file mode 100644\nindex 0000000..33a5270\n--- /dev/null\n+++ b/Source/Grace/Validation/ValidationState.cs\n@@ -0,0 +1,34 @@\n+\ufeffusing System;\n+using System.Collections.Generic;\n+using System.Linq;\n+using System.Text;\n+using System.Threading.Tasks;\n+\n+namespace Grace.Validation\n+{\n+\t/// <summary>\n+\t/// Represents the validation state for an object or property\n+\t/// </summary>\n+\tpublic enum ValidationState\n+\t{\n+\t\t/// <summary>\n+\t\t/// Valid\n+\t\t/// </summary>\n+\t\tValid = 1,\n+\n+\t\t/// <summary>\n+\t\t/// Valid but with a warning\n+\t\t/// </summary>\n+\t\tValidWithWarning = 2,\n+\n+\t\t/// <summary>\n+\t\t/// Invalid\n+\t\t/// </summary>\n+\t\tInvalid = 3,\n+\n+\t\t/// <summary>\n+\t\t/// Invalid because it\'s required and empty\n+\t\t/// </summary>\n+\t\tInvalidRequired = 4\n+\t}\n+}\n', 'commit_subject': 'Starting to move more stuff out of StyleMVVM into the grace namespace.', 'repo_name': 'ipjohnson/Grace', 'committer': {'name': 'ipjohnson', 'email': 'aad8b897b1f50c2c41d73728a2572191a5369e29@yahoo.com', 'time_sec': '1399733332', 'tz_offset': '-360', 'date': {'seconds': '1399733332'}}, 'commit_tree': '7df1a5eabc8dc9d2f2065e536a618a9938c80e58', 'commit_message': 'Starting to move more stuff out of StyleMVVM into the grace namespace.\n', 'language_name': 'C#', 'license': 'mit', 'hunks': "@@ -0,0 +1,34 @@\n+\ufeffusing System;\n+using System.Collections.Generic;\n+using System.Linq;\n+using System.Text;\n+using System.Threading.Tasks;\n+\n+namespace Grace.Validation\n+{\n+\t/// <summary>\n+\t/// Represents the validation state for an object or property\n+\t/// </summary>\n+\tpublic enum ValidationState\n+\t{\n+\t\t/// <summary>\n+\t\t/// Valid\n+\t\t/// </summary>\n+\t\tValid = 1,\n+\n+\t\t/// <summary>\n+\t\t/// Valid but with a warning\n+\t\t/// </summary>\n+\t\tValidWithWarning = 2,\n+\n+\t\t/// <summary>\n+\t\t/// Invalid\n+\t\t/// </summary>\n+\t\tInvalid = 3,\n+\n+\t\t/// <summary>\n+\t\t/// Invalid because it's required and empty\n+\t\t/// </summary>\n+\t\tInvalidRequired = 4\n+\t}\n+}\n", 'addition_count': 34, 'deletion_count': 0, 'src_file': '/dev/null', 'tgt_file': 'b/Source/Grace/Validation/ValidationState.cs', 'file_extension': '.cs', 'before_file': 'ADDFILE', 'message': 'Starting to move more stuff out of StyleMVVM into the grace namespace.\n', 'author_name': 'ipjohnson', 'lang': 'cs'}