Commits

Nick Hodges committed 4fdd5e8

Adding Enterprise Palindrome, Mocking demos

Comments (0)

Files changed (49)

Attributes/AttributesTestProgram.dpr

+program AttributesTestProgram;
+{$APPTYPE CONSOLE}
+uses
+  SysUtils,
+  Classes,
+  RTTI;
+
+type
+
+  TDisplayTextAttribute = class(TCustomAttribute)
+  private
+    FDisplayText: string;
+  public
+    constructor Create(aDisplayText: string);
+    property DisplayText: string read FDisplayText write FDisplayText;
+  end;
+
+constructor TDisplayTextAttribute.Create(aDisplayText: string);
+begin
+  FDisplayText := aDisplayText;
+end;
+
+type
+  TCustomer = Class(TObject)
+  private
+    FFirstName: string;
+    FLastName: string;
+    FStreetAddress: string;
+    FZIP: string;
+    FState: string;
+    FCity: string;
+    FPhone: string;
+  public
+    [TDisplayTextAttribute('First Name')]
+    property FirstName: string read FFirstName write FFirstName;
+    [TDisplayText('Last Name')]
+    property LastName: string read FLastName write FLastName;
+    [TDisplayText('Street Address')]
+    property StreetAddress: string read FStreetAddress write FStreetAddress;
+    [TDisplayText('City')]
+    property City: string read FCity write FCity;
+    [TDisplayText('State')]
+    property State: string read FState write FState;
+    [TDisplayText('ZIP Code')]
+    property ZIP: string read FZIP write FZIP;
+    property Phone: string read FPhone write FPhone;
+  end;
+
+procedure GetAllDisplayTextsForClass(aType: TClass; const aStringList: TStrings);
+var
+  TempContext: TRttiContext;
+  TempProp: TRTTIProperty;
+  TempType: TRttiType;
+  TempName, TempValue: string;
+
+    function GetDisplayTextForProperty(aProp: TRTTIProperty; aPropName: string): string;
+    var
+      TempAttribute: TCustomAttribute;
+    begin
+      Result := '';
+      if aProp <> nil then
+      begin
+        for TempAttribute in aProp.GetAttributes do
+        begin
+          if TempAttribute is TDisplayTextAttribute then
+          begin
+            Result := TDisplayTextAttribute(TempAttribute).DisplayText;
+          end;
+        end;
+      end;
+    end;
+
+begin
+  if aStringList = nil then
+    Exit;
+  aStringList.Clear;
+  TempContext := TRttiContext.Create;
+  try
+    TempType := TempContext.GetType(aType);
+    for TempProp in TempType.GetProperties do
+    begin
+      TempName := TempProp.Name;
+      TempValue := GetDisplayTextForProperty(TempProp, TempName);
+      aStringList.Values[TempName] := TempValue;
+    end;
+  finally
+    TempContext.Free;
+  end;
+
+end;
+
+var
+  SL: TStringList;
+  S: string;
+
+begin
+
+  SL := TStringList.Create;
+  try
+    GetAllDisplayTextsForClass(TCustomer, SL);
+    for S in SL do
+    begin
+      WriteLn(S);
+    end;
+
+  finally
+    SL.Free;
+  end;
+
+  Readln;
+
+end.

Attributes/AttributesTestProgram.dproj

+	<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+		<PropertyGroup>
+			<ProjectGuid>{54C75372-45A0-4577-9A9D-FF534337431B}</ProjectGuid>
+			<ProjectVersion>13.4</ProjectVersion>
+			<MainSource>AttributesTestProgram.dpr</MainSource>
+			<Config Condition="'$(Config)'==''">Debug</Config>
+			<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
+			<Base>True</Base>
+			<AppType>Console</AppType>
+			<FrameworkType>None</FrameworkType>
+			<Platform Condition="'$(Platform)'==''">Win32</Platform>
+			<TargetedPlatforms>1</TargetedPlatforms>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
+			<Base_Win32>true</Base_Win32>
+			<CfgParent>Base</CfgParent>
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
+			<Cfg_1>true</Cfg_1>
+			<CfgParent>Base</CfgParent>
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
+			<Cfg_2>true</Cfg_2>
+			<CfgParent>Base</CfgParent>
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Base)'!=''">
+			<VerInfo_Locale>1033</VerInfo_Locale>
+			<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
+			<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)</DCC_Namespace>
+			<DCC_DependencyCheckOutputName>AttributesTestProgram.exe</DCC_DependencyCheckOutputName>
+			<DCC_ImageBase>00400000</DCC_ImageBase>
+			<DCC_Platform>x86</DCC_Platform>
+			<DCC_E>false</DCC_E>
+			<DCC_N>false</DCC_N>
+			<DCC_S>false</DCC_S>
+			<DCC_F>false</DCC_F>
+			<DCC_K>false</DCC_K>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Base_Win32)'!=''">
+			<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
+			<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
+			<VerInfo_Locale>1033</VerInfo_Locale>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Cfg_1)'!=''">
+			<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
+			<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
+			<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
+			<DCC_DebugInformation>false</DCC_DebugInformation>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Cfg_2)'!=''">
+			<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
+		</PropertyGroup>
+		<ItemGroup>
+			<DelphiCompile Include="$(MainSource)">
+				<MainSource>MainSource</MainSource>
+			</DelphiCompile>
+			<BuildConfiguration Include="Debug">
+				<Key>Cfg_2</Key>
+				<CfgParent>Base</CfgParent>
+			</BuildConfiguration>
+			<BuildConfiguration Include="Base">
+				<Key>Base</Key>
+			</BuildConfiguration>
+			<BuildConfiguration Include="Release">
+				<Key>Cfg_1</Key>
+				<CfgParent>Base</CfgParent>
+			</BuildConfiguration>
+		</ItemGroup>
+		<Import Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')" Project="$(BDS)\Bin\CodeGear.Delphi.Targets"/>
+		<Import Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')" Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj"/>
+		<ProjectExtensions>
+			<Borland.Personality>Delphi.Personality.12</Borland.Personality>
+			<Borland.ProjectType/>
+			<BorlandProject>
+				<Delphi.Personality>
+					<Source>
+						<Source Name="MainSource">AttributesTestProgram.dpr</Source>
+					</Source>
+					<Parameters/>
+					<VersionInfo>
+						<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
+						<VersionInfo Name="AutoIncBuild">False</VersionInfo>
+						<VersionInfo Name="MajorVer">1</VersionInfo>
+						<VersionInfo Name="MinorVer">0</VersionInfo>
+						<VersionInfo Name="Release">0</VersionInfo>
+						<VersionInfo Name="Build">0</VersionInfo>
+						<VersionInfo Name="Debug">False</VersionInfo>
+						<VersionInfo Name="PreRelease">False</VersionInfo>
+						<VersionInfo Name="Special">False</VersionInfo>
+						<VersionInfo Name="Private">False</VersionInfo>
+						<VersionInfo Name="DLL">False</VersionInfo>
+						<VersionInfo Name="Locale">1033</VersionInfo>
+						<VersionInfo Name="CodePage">1252</VersionInfo>
+					</VersionInfo>
+					<VersionInfoKeys>
+						<VersionInfoKeys Name="CompanyName"/>
+						<VersionInfoKeys Name="FileDescription"/>
+						<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
+						<VersionInfoKeys Name="InternalName"/>
+						<VersionInfoKeys Name="LegalCopyright"/>
+						<VersionInfoKeys Name="LegalTrademarks"/>
+						<VersionInfoKeys Name="OriginalFilename"/>
+						<VersionInfoKeys Name="ProductName"/>
+						<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
+						<VersionInfoKeys Name="Comments"/>
+					</VersionInfoKeys>
+				</Delphi.Personality>
+				<Platforms>
+					<Platform value="Win64">False</Platform>
+					<Platform value="OSX32">False</Platform>
+					<Platform value="Win32">True</Platform>
+				</Platforms>
+			</BorlandProject>
+			<ProjectFileVersion>12</ProjectFileVersion>
+		</ProjectExtensions>
+	</Project>

Attributes/AttributesTestProgram.res

Binary file added.

Attributes/nxAttributes.pas

+unit nxAttributes;
+
+interface
+
+type
+
+  TDisplayTextAttribute = class(TCustomAttribute)
+  private
+    FDisplayText: string;
+  public
+    constructor Create(aDisplayText: string);
+    property DisplayText: string read FDisplayText write FDisplayText;
+  end;
+
+implementation
+
+constructor TDisplayTextAttribute.Create(aDisplayText: string);
+begin
+  FDisplayText := aDisplayText;
+end;
+
+
+
+end.

Demo.VirtualInterceptor.dpr

-program Demo.VirtualInterceptor;
-
-{$APPTYPE CONSOLE}
-
-{$R *.res}
-
-uses
-  System.SysUtils,
-  uVirtualInterface in 'uVirtualInterface.pas';
-
-var
-  DemoIntf: IDemoInterface;
-
-begin
-  try
-    DemoIntf :=
-      DoSomething(
-
-      procedure
-      begin
-        WriteLn ('Implementing DoSomething with an Anonymous Method')
-      end
-
-    );
-
-    DemoIntf.DoSomething;
-    WriteLn('If you call TimesTwo on 6, you should get 12.  The actual result is: ', DemoIntf.TimesTwo(6));
-
-    WriteLn;
-
-    DemoIntf :=
-      DoSomething(
-
-      procedure
-      begin
-        WriteLn ('This is a different implementation, changed at runtime.')
-      end
-
-    );
-
-    DemoIntf.DoSomething;
-    WriteLn('If you call TimesTwo on 42, you should get 84.  The actual result is: ', DemoIntf.TimesTwo(42));
-
-  except
-    on E: Exception do
-      Writeln(E.ClassName, ': ', E.Message);
-  end;
-  Readln;
-end.

Demo.VirtualInterceptor.dproj

-	<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-		<PropertyGroup>
-			<ProjectGuid>{379FC496-47A8-419B-91BB-E29FE9D0F3D0}</ProjectGuid>
-			<ProjectVersion>13.4</ProjectVersion>
-			<FrameworkType>None</FrameworkType>
-			<MainSource>Demo.VirtualInterceptor.dpr</MainSource>
-			<Base>True</Base>
-			<Config Condition="'$(Config)'==''">Debug</Config>
-			<Platform Condition="'$(Platform)'==''">Win32</Platform>
-			<TargetedPlatforms>1</TargetedPlatforms>
-			<AppType>Console</AppType>
-		</PropertyGroup>
-		<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
-			<Base>true</Base>
-		</PropertyGroup>
-		<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
-			<Base_Win64>true</Base_Win64>
-			<CfgParent>Base</CfgParent>
-			<Base>true</Base>
-		</PropertyGroup>
-		<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
-			<Base_Win32>true</Base_Win32>
-			<CfgParent>Base</CfgParent>
-			<Base>true</Base>
-		</PropertyGroup>
-		<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''">
-			<Cfg_1>true</Cfg_1>
-			<CfgParent>Base</CfgParent>
-			<Base>true</Base>
-		</PropertyGroup>
-		<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''">
-			<Cfg_1_Win32>true</Cfg_1_Win32>
-			<CfgParent>Cfg_1</CfgParent>
-			<Cfg_1>true</Cfg_1>
-			<Base>true</Base>
-		</PropertyGroup>
-		<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''">
-			<Cfg_2>true</Cfg_2>
-			<CfgParent>Base</CfgParent>
-			<Base>true</Base>
-		</PropertyGroup>
-		<PropertyGroup Condition="'$(Base)'!=''">
-			<DCC_UsePackage>bindcompfmx;fmx;rtl;dbrtl;IndySystem;DbxClientDriver;bindcomp;inetdb;DBXInterBaseDriver;DataSnapCommon;DataSnapClient;DataSnapServer;DataSnapProviderClient;xmlrtl;DbxCommonDriver;IndyProtocols;DBXMySQLDriver;dbxcds;bindengine;soaprtl;DBXOracleDriver;dsnap;DBXInformixDriver;IndyCore;fmxase;DBXFirebirdDriver;inet;fmxobj;inetdbxpress;DBXSybaseASADriver;fmxdae;dbexpress;DataSnapIndy10ServerTransport;IPIndyImpl;$(DCC_UsePackage)</DCC_UsePackage>
-			<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)</DCC_Namespace>
-			<DCC_DcuOutput>.\$(Platform)\$(Config)</DCC_DcuOutput>
-			<DCC_ExeOutput>.\$(Platform)\$(Config)</DCC_ExeOutput>
-			<DCC_E>false</DCC_E>
-			<DCC_N>false</DCC_N>
-			<DCC_S>false</DCC_S>
-			<DCC_F>false</DCC_F>
-			<DCC_K>false</DCC_K>
-		</PropertyGroup>
-		<PropertyGroup Condition="'$(Base_Win64)'!=''">
-			<DCC_UsePackage>DBXOdbcDriver;DBXSybaseASEDriver;vclimg;vclactnband;vcldb;vcldsnap;bindcompvcl;vclie;vcltouch;DBXDb2Driver;websnap;VclSmp;vcl;DBXMSSQLDriver;dsnapcon;vclx;webdsnap;$(DCC_UsePackage)</DCC_UsePackage>
-		</PropertyGroup>
-		<PropertyGroup Condition="'$(Base_Win32)'!=''">
-			<DCC_UsePackage>vcldbx;frx16;TeeDB;Rave100VCL;vclib;Tee;inetdbbde;DBXOdbcDriver;svnui;ibxpress;DBXSybaseASEDriver;vclimg;frxDB16;intrawebdb_120_160;fmi;fs16;FMXTee;TeeUI;vclactnband;vcldb;vcldsnap;bindcompvcl;vclie;vcltouch;Intraweb_120_160;DBXDb2Driver;websnap;vclribbon;frxe16;VclSmp;fsDB16;vcl;DataSnapConnectors;CloudService;DBXMSSQLDriver;CodeSiteExpressPkg;FmxTeeUI;dsnapcon;vclx;webdsnap;svn;bdertl;adortl;$(DCC_UsePackage)</DCC_UsePackage>
-			<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
-			<VerInfo_Locale>1033</VerInfo_Locale>
-			<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
-		</PropertyGroup>
-		<PropertyGroup Condition="'$(Cfg_1)'!=''">
-			<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
-			<DCC_Optimize>false</DCC_Optimize>
-			<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
-			<DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>
-			<DCC_RemoteDebug>true</DCC_RemoteDebug>
-		</PropertyGroup>
-		<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
-			<DCC_DebugDCUs>true</DCC_DebugDCUs>
-			<Manifest_File>None</Manifest_File>
-			<VerInfo_Locale>1033</VerInfo_Locale>
-			<DCC_RemoteDebug>false</DCC_RemoteDebug>
-		</PropertyGroup>
-		<PropertyGroup Condition="'$(Cfg_2)'!=''">
-			<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
-			<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
-			<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
-			<DCC_DebugInformation>false</DCC_DebugInformation>
-		</PropertyGroup>
-		<ItemGroup>
-			<DelphiCompile Include="$(MainSource)">
-				<MainSource>MainSource</MainSource>
-			</DelphiCompile>
-			<DCCReference Include="uVirtualInterface.pas"/>
-			<BuildConfiguration Include="Release">
-				<Key>Cfg_2</Key>
-				<CfgParent>Base</CfgParent>
-			</BuildConfiguration>
-			<BuildConfiguration Include="Base">
-				<Key>Base</Key>
-			</BuildConfiguration>
-			<BuildConfiguration Include="Debug">
-				<Key>Cfg_1</Key>
-				<CfgParent>Base</CfgParent>
-			</BuildConfiguration>
-		</ItemGroup>
-		<ProjectExtensions>
-			<Borland.Personality>Delphi.Personality.12</Borland.Personality>
-			<Borland.ProjectType/>
-			<BorlandProject>
-				<Delphi.Personality>
-					<VersionInfo>
-						<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
-						<VersionInfo Name="AutoIncBuild">False</VersionInfo>
-						<VersionInfo Name="MajorVer">1</VersionInfo>
-						<VersionInfo Name="MinorVer">0</VersionInfo>
-						<VersionInfo Name="Release">0</VersionInfo>
-						<VersionInfo Name="Build">0</VersionInfo>
-						<VersionInfo Name="Debug">False</VersionInfo>
-						<VersionInfo Name="PreRelease">False</VersionInfo>
-						<VersionInfo Name="Special">False</VersionInfo>
-						<VersionInfo Name="Private">False</VersionInfo>
-						<VersionInfo Name="DLL">False</VersionInfo>
-						<VersionInfo Name="Locale">1033</VersionInfo>
-						<VersionInfo Name="CodePage">1252</VersionInfo>
-					</VersionInfo>
-					<VersionInfoKeys>
-						<VersionInfoKeys Name="CompanyName"/>
-						<VersionInfoKeys Name="FileDescription"/>
-						<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
-						<VersionInfoKeys Name="InternalName"/>
-						<VersionInfoKeys Name="LegalCopyright"/>
-						<VersionInfoKeys Name="LegalTrademarks"/>
-						<VersionInfoKeys Name="OriginalFilename"/>
-						<VersionInfoKeys Name="ProductName"/>
-						<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
-						<VersionInfoKeys Name="Comments"/>
-					</VersionInfoKeys>
-					<Source>
-						<Source Name="MainSource">Demo.VirtualInterceptor.dpr</Source>
-					</Source>
-					<Excluded_Packages>
-						<Excluded_Packages Name="$(BDSBIN)\dcloffice2k160.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
-						<Excluded_Packages Name="$(BDSBIN)\dclofficexp160.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
-					</Excluded_Packages>
-				</Delphi.Personality>
-				<Deployment/>
-				<Platforms>
-					<Platform value="Win64">False</Platform>
-					<Platform value="OSX32">False</Platform>
-					<Platform value="Win32">True</Platform>
-				</Platforms>
-			</BorlandProject>
-			<ProjectFileVersion>12</ProjectFileVersion>
-		</ProjectExtensions>
-		<Import Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')" Project="$(BDS)\Bin\CodeGear.Delphi.Targets"/>
-		<Import Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')" Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj"/>
-	</Project>

SpringDemos/Demo.Collections/Demo.Spring.Collections.Stack.dpr

     S := 'RACECAR';
     TellIfPalindrome(S);
 
+    S := 'RACE CAR';
+    TellIfPalindrome(S);
+
     S := 'Madam, I''m adam';
     TellIfPalindrome(S);
 

SpringDemos/Demo.General/EnterprisePalindrome/EnterpisePalindromePackage.dpk

+package EnterpisePalindromePackage;
+
+{$R *.res}
+{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}
+{$ALIGN 8}
+{$ASSERTIONS ON}
+{$BOOLEVAL OFF}
+{$DEBUGINFO ON}
+{$EXTENDEDSYNTAX ON}
+{$IMPORTEDDATA ON}
+{$IOCHECKS ON}
+{$LOCALSYMBOLS ON}
+{$LONGSTRINGS ON}
+{$OPENSTRINGS ON}
+{$OPTIMIZATION OFF}
+{$OVERFLOWCHECKS OFF}
+{$RANGECHECKS OFF}
+{$REFERENCEINFO ON}
+{$SAFEDIVIDE OFF}
+{$STACKFRAMES ON}
+{$TYPEDADDRESS OFF}
+{$VARSTRINGCHECKS ON}
+{$WRITEABLECONST OFF}
+{$MINENUMSIZE 1}
+{$IMAGEBASE $400000}
+{$DEFINE DEBUG}
+{$ENDIF IMPLICITBUILDING}
+{$IMPLICITBUILD ON}
+
+requires
+  rtl;
+
+contains
+  uPalindromeInterfaces in 'uPalindromeInterfaces.pas',
+  uNicksPalindrome in 'uNicksPalindrome.pas',
+  uWarrensPalindrome in 'uWarrensPalindrome.pas',
+  uWoutersPalindrome in 'uWoutersPalindrome.pas',
+  uBaoquansPalindrome in 'uBaoquansPalindrome.pas',
+  uCleanString in 'uCleanString.pas',
+  uIsPalindrome in 'uIsPalindrome.pas';
+
+end.

SpringDemos/Demo.General/EnterprisePalindrome/EnterpisePalindromePackage.dproj

+	<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+		<PropertyGroup>
+			<ProjectGuid>{733F8B9C-C236-48B5-9188-C4F0FA77492F}</ProjectGuid>
+			<MainSource>EnterpisePalindromePackage.dpk</MainSource>
+			<ProjectVersion>13.4</ProjectVersion>
+			<FrameworkType>None</FrameworkType>
+			<Base>True</Base>
+			<Config Condition="'$(Config)'==''">Debug</Config>
+			<Platform Condition="'$(Platform)'==''">Win32</Platform>
+			<TargetedPlatforms>1</TargetedPlatforms>
+			<AppType>Package</AppType>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
+			<Base_Win32>true</Base_Win32>
+			<CfgParent>Base</CfgParent>
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''">
+			<Cfg_1>true</Cfg_1>
+			<CfgParent>Base</CfgParent>
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''">
+			<Cfg_1_Win32>true</Cfg_1_Win32>
+			<CfgParent>Cfg_1</CfgParent>
+			<Cfg_1>true</Cfg_1>
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''">
+			<Cfg_2>true</Cfg_2>
+			<CfgParent>Base</CfgParent>
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Base)'!=''">
+			<DCC_CBuilderOutput>All</DCC_CBuilderOutput>
+			<GenPackage>true</GenPackage>
+			<GenDll>true</GenDll>
+			<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)</DCC_Namespace>
+			<DCC_DcuOutput>.\$(Platform)\$(Config)</DCC_DcuOutput>
+			<DCC_ExeOutput>.\$(Platform)\$(Config)</DCC_ExeOutput>
+			<DCC_E>false</DCC_E>
+			<DCC_N>false</DCC_N>
+			<DCC_S>false</DCC_S>
+			<DCC_F>false</DCC_F>
+			<DCC_K>false</DCC_K>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Base_Win32)'!=''">
+			<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
+			<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
+			<VerInfo_Locale>1033</VerInfo_Locale>
+			<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Cfg_1)'!=''">
+			<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
+			<DCC_Optimize>false</DCC_Optimize>
+			<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
+			<DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>
+			<DCC_RemoteDebug>true</DCC_RemoteDebug>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
+			<DCC_RemoteDebug>false</DCC_RemoteDebug>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Cfg_2)'!=''">
+			<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
+			<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
+			<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
+			<DCC_DebugInformation>false</DCC_DebugInformation>
+		</PropertyGroup>
+		<ItemGroup>
+			<DelphiCompile Include="$(MainSource)">
+				<MainSource>MainSource</MainSource>
+			</DelphiCompile>
+			<DCCReference Include="rtl.dcp"/>
+			<DCCReference Include="uPalindromeInterfaces.pas"/>
+			<DCCReference Include="uNicksPalindrome.pas"/>
+			<DCCReference Include="uWarrensPalindrome.pas"/>
+			<DCCReference Include="uWoutersPalindrome.pas"/>
+			<DCCReference Include="uBaoquansPalindrome.pas"/>
+			<DCCReference Include="uCleanString.pas"/>
+			<DCCReference Include="uIsPalindrome.pas"/>
+			<BuildConfiguration Include="Release">
+				<Key>Cfg_2</Key>
+				<CfgParent>Base</CfgParent>
+			</BuildConfiguration>
+			<BuildConfiguration Include="Base">
+				<Key>Base</Key>
+			</BuildConfiguration>
+			<BuildConfiguration Include="Debug">
+				<Key>Cfg_1</Key>
+				<CfgParent>Base</CfgParent>
+			</BuildConfiguration>
+		</ItemGroup>
+		<ProjectExtensions>
+			<Borland.Personality>Delphi.Personality.12</Borland.Personality>
+			<Borland.ProjectType>Package</Borland.ProjectType>
+			<BorlandProject>
+				<Delphi.Personality>
+					<Source>
+						<Source Name="MainSource">EnterpisePalindromePackage.dpk</Source>
+					</Source>
+					<VersionInfo>
+						<VersionInfo Name="IncludeVerInfo">True</VersionInfo>
+						<VersionInfo Name="AutoIncBuild">False</VersionInfo>
+						<VersionInfo Name="MajorVer">1</VersionInfo>
+						<VersionInfo Name="MinorVer">0</VersionInfo>
+						<VersionInfo Name="Release">0</VersionInfo>
+						<VersionInfo Name="Build">0</VersionInfo>
+						<VersionInfo Name="Debug">False</VersionInfo>
+						<VersionInfo Name="PreRelease">False</VersionInfo>
+						<VersionInfo Name="Special">False</VersionInfo>
+						<VersionInfo Name="Private">False</VersionInfo>
+						<VersionInfo Name="DLL">False</VersionInfo>
+						<VersionInfo Name="Locale">1033</VersionInfo>
+						<VersionInfo Name="CodePage">1252</VersionInfo>
+					</VersionInfo>
+					<VersionInfoKeys>
+						<VersionInfoKeys Name="CompanyName"/>
+						<VersionInfoKeys Name="FileDescription"/>
+						<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
+						<VersionInfoKeys Name="InternalName"/>
+						<VersionInfoKeys Name="LegalCopyright"/>
+						<VersionInfoKeys Name="LegalTrademarks"/>
+						<VersionInfoKeys Name="OriginalFilename"/>
+						<VersionInfoKeys Name="ProductName"/>
+						<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
+						<VersionInfoKeys Name="Comments"/>
+					</VersionInfoKeys>
+				</Delphi.Personality>
+				<Deployment/>
+				<Platforms>
+					<Platform value="Win64">False</Platform>
+					<Platform value="OSX32">False</Platform>
+					<Platform value="Win32">True</Platform>
+				</Platforms>
+			</BorlandProject>
+			<ProjectFileVersion>12</ProjectFileVersion>
+		</ProjectExtensions>
+		<Import Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')" Project="$(BDS)\Bin\CodeGear.Delphi.Targets"/>
+		<Import Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')" Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj"/>
+	</Project>

SpringDemos/Demo.General/EnterprisePalindrome/EnterpisePalindromePackage.res

Binary file added.

SpringDemos/Demo.General/EnterprisePalindrome/EnterprisePalindrome.groupproj

+	<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+		<PropertyGroup>
+			<ProjectGuid>{C5178AE5-6E9D-467A-83F6-D7D4261F6CE8}</ProjectGuid>
+		</PropertyGroup>
+		<ItemGroup>
+			<Projects Include="Test\EnterprisePalindromeTests.dproj">
+				<Dependencies/>
+			</Projects>
+		</ItemGroup>
+		<ProjectExtensions>
+			<Borland.Personality>Default.Personality.12</Borland.Personality>
+			<Borland.ProjectType/>
+			<BorlandProject>
+				<Default.Personality/>
+			</BorlandProject>
+		</ProjectExtensions>
+		<Target Name="EnterprisePalindromeTests">
+			<MSBuild Projects="Test\EnterprisePalindromeTests.dproj"/>
+		</Target>
+		<Target Name="EnterprisePalindromeTests:Clean">
+			<MSBuild Projects="Test\EnterprisePalindromeTests.dproj" Targets="Clean"/>
+		</Target>
+		<Target Name="EnterprisePalindromeTests:Make">
+			<MSBuild Projects="Test\EnterprisePalindromeTests.dproj" Targets="Make"/>
+		</Target>
+		<Target Name="Build">
+			<CallTarget Targets="EnterprisePalindromeTests"/>
+		</Target>
+		<Target Name="Clean">
+			<CallTarget Targets="EnterprisePalindromeTests:Clean"/>
+		</Target>
+		<Target Name="Make">
+			<CallTarget Targets="EnterprisePalindromeTests:Make"/>
+		</Target>
+		<Import Condition="Exists('$(BDS)\Bin\CodeGear.Group.Targets')" Project="$(BDS)\Bin\CodeGear.Group.Targets"/>
+	</Project>

SpringDemos/Demo.General/EnterprisePalindrome/EnterprisePalindromeDemo.dpr

+program EnterprisePalindromeDemo;
+
+{$APPTYPE CONSOLE}
+
+{$R *.res}
+
+uses
+  SysUtils,
+  uBaoquansPalindrome in 'uBaoquansPalindrome.pas',
+  uCleanString in 'uCleanString.pas',
+  uIsPalindrome in 'uIsPalindrome.pas',
+  uNicksPalindrome in 'uNicksPalindrome.pas',
+  uPalindromeInterfaces in 'uPalindromeInterfaces.pas',
+  uWarrensPalindrome in 'uWarrensPalindrome.pas',
+  uWoutersPalindrome in 'uWoutersPalindrome.pas';
+
+var
+    S: string;
+
+begin
+  try
+    repeat
+      Write('Enter a string to test for Palindrome-ness ("exit" to quit) : ');
+      ReadLn(S);
+      if TPalindrome.IsPalindrome(S) then
+      begin
+        WriteLn('"', S, '"',' is a palindrome! (Used ', TPalindrome.LastPalindromeUsed, ' to solve)');
+      end else
+      begin
+        WriteLn('"', S, '"',' is NOT a palindrome! (Used ', TPalindrome.LastPalindromeUsed, ' to solve)');
+      end;
+    until Uppercase(S) = 'EXIT';
+  except
+    on E: Exception do
+      Writeln(E.ClassName, ': ', E.Message);
+  end;
+
+end.

SpringDemos/Demo.General/EnterprisePalindrome/EnterprisePalindromeDemo.dproj

+	<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+		<PropertyGroup>
+			<ProjectGuid>{6EA546D9-FEFE-4429-BD56-D333694842D2}</ProjectGuid>
+			<ProjectVersion>13.4</ProjectVersion>
+			<FrameworkType>None</FrameworkType>
+			<MainSource>EnterprisePalindromeDemo.dpr</MainSource>
+			<Base>True</Base>
+			<Config Condition="'$(Config)'==''">Debug</Config>
+			<Platform Condition="'$(Platform)'==''">Win32</Platform>
+			<TargetedPlatforms>1</TargetedPlatforms>
+			<AppType>Console</AppType>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
+			<Base_Win64>true</Base_Win64>
+			<CfgParent>Base</CfgParent>
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
+			<Base_Win32>true</Base_Win32>
+			<CfgParent>Base</CfgParent>
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''">
+			<Cfg_1>true</Cfg_1>
+			<CfgParent>Base</CfgParent>
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''">
+			<Cfg_1_Win32>true</Cfg_1_Win32>
+			<CfgParent>Cfg_1</CfgParent>
+			<Cfg_1>true</Cfg_1>
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''">
+			<Cfg_2>true</Cfg_2>
+			<CfgParent>Base</CfgParent>
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Base)'!=''">
+			<DCC_UsePackage>bindcompfmx;fmx;rtl;dbrtl;IndySystem;DbxClientDriver;bindcomp;inetdb;DBXInterBaseDriver;DataSnapCommon;DataSnapClient;DataSnapServer;DataSnapProviderClient;xmlrtl;DbxCommonDriver;IndyProtocols;DBXMySQLDriver;dbxcds;soaprtl;bindengine;DBXOracleDriver;dsnap;DBXInformixDriver;IndyCore;fmxase;DBXFirebirdDriver;inet;fmxobj;inetdbxpress;DBXSybaseASADriver;fmxdae;dbexpress;DataSnapIndy10ServerTransport;IPIndyImpl;$(DCC_UsePackage)</DCC_UsePackage>
+			<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)</DCC_Namespace>
+			<DCC_DcuOutput>.\$(Platform)\$(Config)</DCC_DcuOutput>
+			<DCC_ExeOutput>.\$(Platform)\$(Config)</DCC_ExeOutput>
+			<DCC_E>false</DCC_E>
+			<DCC_N>false</DCC_N>
+			<DCC_S>false</DCC_S>
+			<DCC_F>false</DCC_F>
+			<DCC_K>false</DCC_K>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Base_Win64)'!=''">
+			<DCC_UsePackage>DBXOdbcDriver;DBXSybaseASEDriver;vclimg;vclactnband;vcldb;bindcompvcl;vcldsnap;vclie;vcltouch;DBXDb2Driver;websnap;VclSmp;vcl;DBXMSSQLDriver;dsnapcon;vclx;webdsnap;$(DCC_UsePackage)</DCC_UsePackage>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Base_Win32)'!=''">
+			<DCC_UsePackage>vcldbx;TeeDB;Rave100VCL;vclib;Tee;inetdbbde;DBXOdbcDriver;svnui;ibxpress;DBXSybaseASEDriver;vclimg;intrawebdb_120_160;fmi;vclactnband;FMXTee;vcldb;TeeUI;bindcompvcl;vcldsnap;vclie;vcltouch;Intraweb_120_160;DBXDb2Driver;websnap;vclribbon;VclSmp;vcl;DataSnapConnectors;CodeSiteExpressPkg;CloudService;DBXMSSQLDriver;FmxTeeUI;dsnapcon;vclx;webdsnap;svn;bdertl;adortl;$(DCC_UsePackage)</DCC_UsePackage>
+			<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
+			<VerInfo_Locale>1033</VerInfo_Locale>
+			<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Cfg_1)'!=''">
+			<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
+			<DCC_Optimize>false</DCC_Optimize>
+			<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
+			<DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>
+			<DCC_RemoteDebug>true</DCC_RemoteDebug>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
+			<DCC_RemoteDebug>false</DCC_RemoteDebug>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Cfg_2)'!=''">
+			<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
+			<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
+			<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
+			<DCC_DebugInformation>false</DCC_DebugInformation>
+		</PropertyGroup>
+		<ItemGroup>
+			<DelphiCompile Include="$(MainSource)">
+				<MainSource>MainSource</MainSource>
+			</DelphiCompile>
+			<DCCReference Include="uBaoquansPalindrome.pas"/>
+			<DCCReference Include="uCleanString.pas"/>
+			<DCCReference Include="uIsPalindrome.pas"/>
+			<DCCReference Include="uNicksPalindrome.pas"/>
+			<DCCReference Include="uPalindromeInterfaces.pas"/>
+			<DCCReference Include="uWarrensPalindrome.pas"/>
+			<DCCReference Include="uWoutersPalindrome.pas"/>
+			<BuildConfiguration Include="Release">
+				<Key>Cfg_2</Key>
+				<CfgParent>Base</CfgParent>
+			</BuildConfiguration>
+			<BuildConfiguration Include="Base">
+				<Key>Base</Key>
+			</BuildConfiguration>
+			<BuildConfiguration Include="Debug">
+				<Key>Cfg_1</Key>
+				<CfgParent>Base</CfgParent>
+			</BuildConfiguration>
+		</ItemGroup>
+		<ProjectExtensions>
+			<Borland.Personality>Delphi.Personality.12</Borland.Personality>
+			<Borland.ProjectType/>
+			<BorlandProject>
+				<Delphi.Personality>
+					<VersionInfo>
+						<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
+						<VersionInfo Name="AutoIncBuild">False</VersionInfo>
+						<VersionInfo Name="MajorVer">1</VersionInfo>
+						<VersionInfo Name="MinorVer">0</VersionInfo>
+						<VersionInfo Name="Release">0</VersionInfo>
+						<VersionInfo Name="Build">0</VersionInfo>
+						<VersionInfo Name="Debug">False</VersionInfo>
+						<VersionInfo Name="PreRelease">False</VersionInfo>
+						<VersionInfo Name="Special">False</VersionInfo>
+						<VersionInfo Name="Private">False</VersionInfo>
+						<VersionInfo Name="DLL">False</VersionInfo>
+						<VersionInfo Name="Locale">1033</VersionInfo>
+						<VersionInfo Name="CodePage">1252</VersionInfo>
+					</VersionInfo>
+					<VersionInfoKeys>
+						<VersionInfoKeys Name="CompanyName"/>
+						<VersionInfoKeys Name="FileDescription"/>
+						<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
+						<VersionInfoKeys Name="InternalName"/>
+						<VersionInfoKeys Name="LegalCopyright"/>
+						<VersionInfoKeys Name="LegalTrademarks"/>
+						<VersionInfoKeys Name="OriginalFilename"/>
+						<VersionInfoKeys Name="ProductName"/>
+						<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
+						<VersionInfoKeys Name="Comments"/>
+					</VersionInfoKeys>
+					<Source>
+						<Source Name="MainSource">EnterprisePalindromeDemo.dpr</Source>
+					</Source>
+				</Delphi.Personality>
+				<Deployment/>
+				<Platforms>
+					<Platform value="Win64">False</Platform>
+					<Platform value="OSX32">False</Platform>
+					<Platform value="Win32">True</Platform>
+				</Platforms>
+				<UnitTesting>
+					<TestProjectName>C:\Code\NickDemoCode\SpringDemos\Demo.General\EnterprisePalindrome\Test\EnterprisePalindromeTests.dproj</TestProjectName>
+				</UnitTesting>
+			</BorlandProject>
+			<ProjectFileVersion>12</ProjectFileVersion>
+		</ProjectExtensions>
+		<Import Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')" Project="$(BDS)\Bin\CodeGear.Delphi.Targets"/>
+		<Import Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')" Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj"/>
+	</Project>

SpringDemos/Demo.General/EnterprisePalindrome/EnterprisePalindromeDemo.res

Binary file added.

SpringDemos/Demo.General/EnterprisePalindrome/Test/EnterprisePalindromeTests.dpr

+program EnterprisePalindromeTests;
+{
+
+  Delphi DUnit Test Project
+  -------------------------
+  This project contains the DUnit test framework and the GUI/Console test runners.
+  Add "CONSOLE_TESTRUNNER" to the conditional defines entry in the project options
+  to use the console test runner.  Otherwise the GUI test runner will be used by
+  default.
+
+}
+
+{$IFDEF CONSOLE_TESTRUNNER}
+{$APPTYPE CONSOLE}
+{$ENDIF}
+
+uses
+  Forms,
+  TestFramework,
+  GUITestRunner,
+  TextTestRunner,
+  TestuIsPalindrome in 'TestuIsPalindrome.pas',
+  uIsPalindrome in '..\uIsPalindrome.pas',
+  uBaoquansPalindrome in '..\uBaoquansPalindrome.pas',
+  uNicksPalindrome in '..\uNicksPalindrome.pas',
+  uWarrensPalindrome in '..\uWarrensPalindrome.pas',
+  uWoutersPalindrome in '..\uWoutersPalindrome.pas',
+  uPalindromeInterfaces in '..\uPalindromeInterfaces.pas',
+  uCleanString in '..\uCleanString.pas';
+
+{$R *.RES}
+
+begin
+  Application.Initialize;
+  if IsConsole then
+    with TextTestRunner.RunRegisteredTests do
+      Free
+  else
+    GUITestRunner.RunRegisteredTests;
+end.
+

SpringDemos/Demo.General/EnterprisePalindrome/Test/EnterprisePalindromeTests.dproj

+	<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+		<PropertyGroup>
+			<ProjectGuid>{D397BF70-1041-41DC-B645-457A51082649}</ProjectGuid>
+			<ProjectVersion>13.4</ProjectVersion>
+			<FrameworkType>VCL</FrameworkType>
+			<Base>True</Base>
+			<Config Condition="'$(Config)'==''">Debug</Config>
+			<Platform Condition="'$(Platform)'==''">Win32</Platform>
+			<TargetedPlatforms>1</TargetedPlatforms>
+			<AppType>Application</AppType>
+			<MainSource>EnterprisePalindromeTests.dpr</MainSource>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
+			<Base_Win64>true</Base_Win64>
+			<CfgParent>Base</CfgParent>
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
+			<Base_Win32>true</Base_Win32>
+			<CfgParent>Base</CfgParent>
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''">
+			<Cfg_1>true</Cfg_1>
+			<CfgParent>Base</CfgParent>
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''">
+			<Cfg_1_Win32>true</Cfg_1_Win32>
+			<CfgParent>Cfg_1</CfgParent>
+			<Cfg_1>true</Cfg_1>
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''">
+			<Cfg_2>true</Cfg_2>
+			<CfgParent>Base</CfgParent>
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Base)'!=''">
+			<DCC_UnitSearchPath>$(BDS)\Source\DUnit\src;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
+			<DCC_UsePackage>bindcompfmx;fmx;rtl;dbrtl;IndySystem;DbxClientDriver;bindcomp;inetdb;DBXInterBaseDriver;DataSnapCommon;DataSnapClient;DataSnapServer;DataSnapProviderClient;xmlrtl;DbxCommonDriver;IndyProtocols;DBXMySQLDriver;dbxcds;soaprtl;bindengine;DBXOracleDriver;dsnap;DBXInformixDriver;IndyCore;fmxase;DBXFirebirdDriver;inet;fmxobj;inetdbxpress;DBXSybaseASADriver;fmxdae;dbexpress;DataSnapIndy10ServerTransport;IPIndyImpl;$(DCC_UsePackage)</DCC_UsePackage>
+			<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace)</DCC_Namespace>
+			<DCC_Define>_CONSOLE_TESTRUNNER;$(DCC_Define)</DCC_Define>
+			<DCC_DcuOutput>.</DCC_DcuOutput>
+			<DCC_ExeOutput>.\$(Platform)\$(Config)</DCC_ExeOutput>
+			<DCC_E>false</DCC_E>
+			<DCC_N>false</DCC_N>
+			<DCC_S>false</DCC_S>
+			<DCC_F>false</DCC_F>
+			<DCC_K>false</DCC_K>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Base_Win64)'!=''">
+			<DCC_UsePackage>DBXOdbcDriver;DataBindings;DBXSybaseASEDriver;vclimg;vclactnband;vcldb;bindcompvcl;vcldsnap;vclie;vcltouch;DBXDb2Driver;websnap;VclSmp;vcl;DBXMSSQLDriver;dsnapcon;vclx;webdsnap;DSharp.Core;$(DCC_UsePackage)</DCC_UsePackage>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Base_Win32)'!=''">
+			<DCC_UsePackage>vcldbx;TeeDB;VirtualTreesD;Rave100VCL;vclib;Tee;inetdbbde;DBXOdbcDriver;DataBindings;svnui;ibxpress;DBXSybaseASEDriver;vclimg;intrawebdb_120_160;fmi;vclactnband;FMXTee;vcldb;TeeUI;bindcompvcl;vcldsnap;vclie;vcltouch;Intraweb_120_160;DBXDb2Driver;websnap;vclribbon;VclSmp;vcl;DataSnapConnectors;CodeSiteExpressPkg;CloudService;DBXMSSQLDriver;FmxTeeUI;dsnapcon;vclx;webdsnap;svn;DSharp.Core;bdertl;adortl;$(DCC_UsePackage)</DCC_UsePackage>
+			<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
+			<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
+			<VerInfo_Locale>1033</VerInfo_Locale>
+			<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
+			<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Cfg_1)'!=''">
+			<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
+			<DCC_Optimize>false</DCC_Optimize>
+			<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
+			<DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>
+			<DCC_RemoteDebug>true</DCC_RemoteDebug>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
+			<DCC_RemoteDebug>false</DCC_RemoteDebug>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Cfg_2)'!=''">
+			<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
+			<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
+			<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
+			<DCC_DebugInformation>false</DCC_DebugInformation>
+		</PropertyGroup>
+		<ItemGroup>
+			<DelphiCompile Include="$(MainSource)">
+				<MainSource>MainSource</MainSource>
+			</DelphiCompile>
+			<DCCReference Include="TestuIsPalindrome.pas"/>
+			<DCCReference Include="..\uIsPalindrome.pas"/>
+			<DCCReference Include="..\uBaoquansPalindrome.pas"/>
+			<DCCReference Include="..\uNicksPalindrome.pas"/>
+			<DCCReference Include="..\uWarrensPalindrome.pas"/>
+			<DCCReference Include="..\uWoutersPalindrome.pas"/>
+			<DCCReference Include="..\uPalindromeInterfaces.pas"/>
+			<DCCReference Include="..\uCleanString.pas"/>
+			<BuildConfiguration Include="Release">
+				<Key>Cfg_2</Key>
+				<CfgParent>Base</CfgParent>
+			</BuildConfiguration>
+			<BuildConfiguration Include="Base">
+				<Key>Base</Key>
+			</BuildConfiguration>
+			<BuildConfiguration Include="Debug">
+				<Key>Cfg_1</Key>
+				<CfgParent>Base</CfgParent>
+			</BuildConfiguration>
+		</ItemGroup>
+		<ProjectExtensions>
+			<Borland.Personality>Delphi.Personality.12</Borland.Personality>
+			<Borland.ProjectType/>
+			<BorlandProject>
+				<Delphi.Personality>
+					<VersionInfo>
+						<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
+						<VersionInfo Name="AutoIncBuild">False</VersionInfo>
+						<VersionInfo Name="MajorVer">1</VersionInfo>
+						<VersionInfo Name="MinorVer">0</VersionInfo>
+						<VersionInfo Name="Release">0</VersionInfo>
+						<VersionInfo Name="Build">0</VersionInfo>
+						<VersionInfo Name="Debug">False</VersionInfo>
+						<VersionInfo Name="PreRelease">False</VersionInfo>
+						<VersionInfo Name="Special">False</VersionInfo>
+						<VersionInfo Name="Private">False</VersionInfo>
+						<VersionInfo Name="DLL">False</VersionInfo>
+						<VersionInfo Name="Locale">1033</VersionInfo>
+						<VersionInfo Name="CodePage">1252</VersionInfo>
+					</VersionInfo>
+					<VersionInfoKeys>
+						<VersionInfoKeys Name="CompanyName"/>
+						<VersionInfoKeys Name="FileDescription"/>
+						<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
+						<VersionInfoKeys Name="InternalName"/>
+						<VersionInfoKeys Name="LegalCopyright"/>
+						<VersionInfoKeys Name="LegalTrademarks"/>
+						<VersionInfoKeys Name="OriginalFilename"/>
+						<VersionInfoKeys Name="ProductName"/>
+						<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
+						<VersionInfoKeys Name="Comments"/>
+					</VersionInfoKeys>
+					<Source>
+						<Source Name="MainSource">EnterprisePalindromeTests.dpr</Source>
+					</Source>
+				</Delphi.Personality>
+				<Deployment/>
+				<Platforms>
+					<Platform value="Win64">False</Platform>
+					<Platform value="OSX32">False</Platform>
+					<Platform value="Win32">True</Platform>
+				</Platforms>
+				<UnitTesting>
+					<TestFramework>DUnit / Delphi Win32</TestFramework>
+					<TestRunner>GUI</TestRunner>
+					<SourceProjectName>C:\Code\NickDemoCode\SpringDemos\Demo.General\EnterprisePalindrome\EnterprisePalindromeDemo.dproj</SourceProjectName>
+					<TestProjectName/>
+				</UnitTesting>
+			</BorlandProject>
+			<ProjectFileVersion>12</ProjectFileVersion>
+		</ProjectExtensions>
+		<Import Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')" Project="$(BDS)\Bin\CodeGear.Delphi.Targets"/>
+		<Import Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')" Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj"/>
+	</Project>

SpringDemos/Demo.General/EnterprisePalindrome/Test/EnterprisePalindromeTests.res

Binary file added.

SpringDemos/Demo.General/EnterprisePalindrome/Test/TestuIsPalindrome.pas

+unit TestuIsPalindrome;
+{
+
+  Delphi DUnit Test Case
+  ----------------------
+  This unit contains a skeleton test case class generated by the Test Case Wizard.
+  Modify the generated code to correctly setup and call the methods from the unit 
+  being tested.
+
+}
+
+interface
+
+uses
+    TestFramework
+  , Spring.Services
+  , Spring.Container
+  , uIsPalindrome
+  , Spring.Collections
+  , Spring.Collections.Lists
+  , uPalindromeInterfaces
+//  , uNicksPalindrome    //1
+//  , uWarrensPalindrome  //2
+//  , uWoutersPalindrome  //3
+/// , uBaoquansPalindrome //4
+
+
+  ;
+
+type
+  // Test methods for class TPalindrome
+
+  TestTPalindrome = class(TTestCase)
+  strict private
+
+    Palindrome1: IIsPalindrome;
+    Palindrome2: IIsPalindrome;
+    Palindrome3: IIsPalindrome;
+    Palindrome4: IIsPalindrome;
+
+    TestStrings: IList<string>;
+    procedure Add(aString: string);
+  public
+    procedure SetUp; override;
+    procedure TearDown; override;
+  published
+    procedure TestIsPalindrome;
+    procedure TestBlankString;
+  end;
+
+implementation
+
+uses
+     SysUtils;
+
+
+procedure TestTPalindrome.Add(aString: string);
+begin
+  if TestStrings = nil then
+    raise Exception.Create('TestStrings not created yet.....');
+  TestStrings.Add(aString);
+end;
+
+procedure TestTPalindrome.SetUp;
+begin
+//  GlobalContainer.Build;
+  Palindrome1 := ServiceLocator.GetService<IIsPalindrome>(cPalindrome + '1');
+  Palindrome2 := ServiceLocator.GetService<IIsPalindrome>(cPalindrome + '2');
+  Palindrome3 := ServiceLocator.GetService<IIsPalindrome>(cPalindrome + '3');
+  Palindrome4 := ServiceLocator.GetService<IIsPalindrome>(cPalindrome + '4');
+
+  TestStrings := TCollections.CreateList<string>;
+  Add('racecar');
+  Add('A man. A plan. A canal.  Panama.');
+  Add('Able was I ere I saw Elba');
+  Add('Madam in Eden, I''m Adam');
+  Add('Doc, note: I dissent. A fast never prevents a fatness. I diet on cod.');
+  TestStrings.Add('Never odd or even');
+  TestStrings.Add('Rise to vote sir');
+  TestStrings.Add('Otto');
+  TestStrings.Add('Bob');
+  TestStrings.Add('Anna');
+  TestStrings.Add('Stanley Yelnats');
+  TestStrings.Add('Straw? No, too stupid a fad. I put soot on warts');
+
+  TestStrings.Add('Sums are not set as a test on Erasmus');
+  TestStrings.Add('Did I trap a rat & tar a part? I did.');
+  TestStrings.Add('aba');
+  TestStrings.Add('abbba');
+  TestStrings.Add('Dennis, Nell, Edna, Leon, Nedra, Anita,' +
+                  ' Rolf, Nora, Alice, Carol, Leo, Jane, Reed,' +
+                  ' Dena, Dale, Basil, Rae, Penny, Lana, Dave,' +
+                  ' Denny, Lena, Ida, Bernadette, Ben, Ray, Lila,' +
+                  ' Nina, Jo, Ira, Mara, Sara, Mario, Jan, Ina,' +
+                  ' Lily, Arne, Bette, Dan, Reba, Diane, Lynn, Ed,' +
+                  ' Eva, Dana, Lynne, Pearl, Isabel, Ada, Ned, Dee,' +
+                  ' Rena, Joel, Lora, Cecil, Aaron, Flora, Tina, Arden, Noel, and Ellen sinned.'
+                 );
+
+  TestStrings.Add('Mr. Owl Ate My Metal Worm');
+  TestStrings.Add('Won''t cat lovers revolt? Act now!');
+
+end;
+
+procedure TestTPalindrome.TearDown;
+begin
+
+end;
+
+procedure TestTPalindrome.TestBlankString;
+var
+  ReturnValue: Boolean;
+  aString: string;
+begin
+  aString := '';
+  ReturnValue := TPalindrome.IsPalindrome(aString);
+  CheckFalse(ReturnValue, Format('Palindrome named %s failed to return false for an empty string', [TPalindrome.LastPalindromeUsed]));
+end;
+
+procedure TestTPalindrome.TestIsPalindrome;
+var
+  ReturnValue: Boolean;
+  aString: string;
+begin
+
+  for aString in TestStrings do
+  begin
+
+    ReturnValue := Palindrome1.IsPalindrome(aString);
+    Check(ReturnValue, Format(cPalindrome + '%d failed on: %s', [1, aString]));
+
+//    ReturnValue := Palindrome2.IsPalindrome(aString);
+//    Check(ReturnValue, Format(cPalindrome + '%d failed on: %s', [2, aString]));
+
+    ReturnValue := Palindrome3.IsPalindrome(aString);
+    Check(ReturnValue, Format(cPalindrome + '%d failed on: %s', [3, aString]));
+
+    ReturnValue := Palindrome4.IsPalindrome(aString);
+    Check(ReturnValue, Format(cPalindrome + '%d failed on: %s', [4, aString]));
+  end;
+end;
+
+initialization
+  // Register any test cases with the test runner
+  RegisterTest(TestTPalindrome.Suite);
+end.
+

SpringDemos/Demo.General/EnterprisePalindrome/Test/Win32/Debug/dunit.ini

+[GUITestRunner Config]
+AutoSave=1
+Left=100
+Top=100
+Width=1008
+Height=504
+Maximized=0
+UseRegistry=0
+ResultsPanel.Height=174
+ErrorMessage.Height=75
+ErrorMessage.Visible=1
+FailureList.ColumnWidth[0]=120
+FailureList.ColumnWidth[1]=255
+FailureList.ColumnWidth[2]=318
+FailureList.ColumnWidth[3]=287
+HideTestNodesOnOpen=0
+BreakOnFailures=0
+FailOnNoChecksExecuted=0
+FailOnMemoryLeaked=0
+IgnoreSetUpTearDownLeaks=0
+ReportMemoryLeakTypes=0
+SelectTestedNode=1
+WarnOnFailTestOverride=0
+PopupX=350
+PopupY=30
+

SpringDemos/Demo.General/EnterprisePalindrome/uBaoquansPalindrome.pas

+unit uBaoquansPalindrome;
+
+interface
+
+implementation
+
+uses
+       uPalindromeInterfaces
+     , Character
+     , Spring.Collections
+     , Spring.Container
+     , Spring.Services
+     ;
+
+type
+
+  TBaoquansPalindrome = class(TInterfacedObject, IIsPalindrome)
+  public
+    function IsPalindrome(const s: string): Boolean;
+  end;
+
+function TBaoquansPalindrome.IsPalindrome(const s: string): Boolean;
+var
+  stack: IStack<Char>;
+  c: Char;
+begin
+  stack := TCollections.CreateStack<Char>;
+  for c in s do
+  begin
+    if TCharacter.IsLetter(c) then
+      stack.Push(TCharacter.ToLower(c));
+  end;
+  Result := stack.EqualsTo(stack.Reversed);
+end;
+
+initialization
+  GlobalContainer.RegisterComponent<TBaoquansPalindrome>.Implements<IIsPalindrome>((cPalindrome + '4'));
+
+end.

SpringDemos/Demo.General/EnterprisePalindrome/uCleanString.pas

+unit uCleanString;
+
+interface
+
+implementation
+
+uses
+       uPalindromeInterfaces
+     , Spring.Collections
+       {$IF CompilerVersion >= 23.0}
+     , System.SysUtils
+       {$ELSE}
+     , SysUtils
+       {$IFEND}
+     , Spring.Container
+     , Spring.Services
+     ;
+
+
+type
+  TNicksCleanString = class(TInterfacedObject, ICleanString)
+    function CleanString(const aString: string): string;
+  end;
+
+function TNicksCleanString.CleanString(const aString: string): string;
+var
+  C: Char;
+begin
+  // Remove all non-alpha chars and make all lower case
+  // Spaces don't matter, so let's count only letters
+  Result := '';
+  for C in LowerCase(aString) do
+  begin
+    if CharInSet(C, ['a'..'z']) then
+    begin
+      Result := Result + C;
+    end;
+  end;
+end;
+
+
+initialization
+  GlobalContainer.RegisterComponent<TNicksCleanString>.Implements<ICleanString>;
+
+end.

SpringDemos/Demo.General/EnterprisePalindrome/uIsPalindrome.pas

+unit uIsPalindrome;
+
+interface
+
+type
+  TPalindrome = class
+    class var LastPalindromeUsed: string;
+    class function IsPalindrome(const aString: string): Boolean;
+  end;
+
+implementation
+
+uses
+      uPalindromeInterfaces
+    , Spring.Container
+    , Spring.Services
+      {$IF CompilerVersion >= 23.0}
+    , System.SysUtils
+      {$ELSE}
+    , SysUtils
+      {$IFEND}
+    ;
+
+class function TPalindrome.IsPalindrome(const aString: string): Boolean;
+var
+  PalindromeService: IIsPalindrome;
+begin
+ // GlobalContainer.Build;
+  Result := False;
+  if Length(aString) > 0 then
+  begin
+    TPalindrome.LastPalindromeUsed := cPalindrome + IntToStr(Random(NumberOfPalindromes) + 1);
+    PalindromeService := ServiceLocator.GetService<IIsPalindrome>(TPalindrome.LastPalindromeUsed);
+    Result := PalindromeService.IsPalindrome(aString);
+  end;
+end;
+
+end.

SpringDemos/Demo.General/EnterprisePalindrome/uNicksPalindrome.pas

+unit uNicksPalindrome;
+
+interface
+
+implementation
+
+uses
+       uPalindromeInterfaces
+     , Spring.Collections
+       {$IF CompilerVersion >= 23.0}
+     , System.SysUtils
+       {$ELSE}
+     , SysUtils
+       {$IFEND}
+     , Spring.Container
+     , Spring.Services
+     ;
+
+type
+ TNicksPalindrome = class(TInterfacedObject, IIsPalindrome)
+  private
+    [Inject]
+    FCleanString: ICleanString;
+  public
+    function IsPalindrome(const aString: string): Boolean;
+  end;
+
+function TNicksPalindrome.IsPalindrome(const aString: string): Boolean;
+var
+  Stack: IStack<Char>;
+  C: Char;
+  NoSpaces: string;
+  Temp: string;
+begin
+  NoSpaces := FCleanString.CleanString(aString);
+
+  Stack := TCollections.CreateStack<Char>;
+  for C in NoSpaces do
+  begin
+    Stack.Push(C);
+  end;
+  Temp := '';
+  repeat
+    Temp := Temp + Stack.Pop;
+  until Stack.Count = 0;
+  Result := Temp = NoSpaces;
+end;
+
+
+function IsPalindrome(const aString: string): Boolean;
+var
+  PalindromeService: IIsPalindrome;
+begin
+  GlobalContainer.Build;
+  PalindromeService := ServiceLocator.GetService<IIsPalindrome>('Palindrome' + IntToStr(Random(4) + 1));
+  Result := PalindromeService.IsPalindrome(aString);
+end;
+
+initialization
+  GlobalContainer.RegisterComponent<TNicksPalindrome>.Implements<IIsPalindrome>(cPalindrome + '1');
+
+
+end.

SpringDemos/Demo.General/EnterprisePalindrome/uPalindromeInterfaces.pas

+unit uPalindromeInterfaces;
+
+interface
+
+type
+  ICleanString = Interface(IInterface)
+    ['{B86A5A12-A2AF-4073-BB20-45D19D87ADDE}']
+    function CleanString(const aString: string): string;
+  End;
+
+  IIsPalindrome = Interface(IInterface)
+    ['{207B33AD-551A-4FC2-83C3-AAB4F01004F4}']
+    function IsPalindrome(const aString: string): Boolean;
+  End;
+
+const
+  NumberOfPalindromes = 4;
+  cPalindrome = 'Palindrome';
+
+implementation
+
+end.

SpringDemos/Demo.General/EnterprisePalindrome/uWarrensPalindrome.pas

+unit uWarrensPalindrome;
+
+interface
+
+implementation
+
+uses
+       uPalindromeInterfaces
+       {$IF CompilerVersion >= 23.0}
+     , System.SysUtils
+       {$ELSE}
+     , SysUtils
+       {$IFEND}
+     , Spring.Services
+     , Spring.Container
+     ;
+
+type
+  TWarrensPalindrome = class(TInterfacedObject, IIsPalindrome)
+  private
+    [Inject]
+    FCleanString: ICleanString;
+  public
+    function IsPalindrome(const aString: string): Boolean;
+  end;
+
+function TWarrensPalindrome.IsPalindrome(const aString: string): Boolean;
+var
+  n, i: Integer;
+  str: string;
+begin
+  result := false;
+  str := FCleanString.CleanString(aString);
+  n := length(aString);
+  for i := 0 to n div 2 do
+    if Uppercase(str[i]) <> Uppercase(str[n-i]) then exit;
+  result := true;
+end;
+
+initialization
+  GlobalContainer.RegisterComponent<TWarrensPalindrome>.Implements<IIsPalindrome>((cPalindrome + '2')).InjectField('FCleanString');
+
+end.

SpringDemos/Demo.General/EnterprisePalindrome/uWoutersPalindrome.pas

+unit uWoutersPalindrome;
+
+interface
+
+implementation
+
+uses
+       uPalindromeInterfaces
+       {$IF CompilerVersion >= 23.0}
+     , System.SysUtils
+       {$ELSE}
+     , SysUtils
+       {$IFEND}
+     , Character
+     , Spring.Container
+     ;
+
+type
+  TWoutersPalindrome = class(TInterfacedObject, IIsPalindrome)
+  public
+    function IsPalindrome(const Text: string): Boolean;
+  end;
+
+function TWoutersPalindrome.IsPalindrome(const Text: string): Boolean;
+var
+  l,r: integer;
+begin
+  l := 1; r := Length(Text); Result := False;
+  while l<r do
+  begin
+    if not IsLetter(Text[l]) then
+      Inc(l)
+    else if not IsLetter(Text[r]) then
+      Dec(r)
+    else if ToLower(Text[l]) <> ToLower(Text[r]) then
+      Exit(False)
+    else
+    begin
+      Inc(l); Dec(r);
+      if not Result then
+        Result := True;
+    end;
+  end;
+end;
+
+initialization
+  GlobalContainer.RegisterComponent<TWoutersPalindrome>.Implements<IIsPalindrome>((cPalindrome + '3'));
+
+end.

SpringDemos/Demo.General/uPredicateDemo.pas

 uses
     Spring
   , Spring.Collections
+  , Spring.Collections.Lists
   ;
 
 

SpringDemos/SpringDemosProjectGroup.groupproj

 			<Projects Include="..\..\DelphiSpring\Samples\SpringDemos\Demo.DependencyInjection\Demo.Spring.DependencyInjection.dproj">
 				<Dependencies/>
 			</Projects>
+			<Projects Include="..\..\DelphiSpring\Samples\SpringDemos\Demo.DependencyInjection\MultipleImplementations\Demo.Spring.MultipleImplementations.dproj">
+				<Dependencies/>
+			</Projects>
 		</ItemGroup>
 		<ProjectExtensions>
 			<Borland.Personality>Default.Personality.12</Borland.Personality>
 		<Target Name="Demo_Spring_DependencyInjection:Make">
 			<MSBuild Projects="..\..\DelphiSpring\Samples\SpringDemos\Demo.DependencyInjection\Demo.Spring.DependencyInjection.dproj" Targets="Make"/>
 		</Target>
+		<Target Name="Demo_Spring_MultipleImplementations">
+			<MSBuild Projects="..\..\DelphiSpring\Samples\SpringDemos\Demo.DependencyInjection\MultipleImplementations\Demo.Spring.MultipleImplementations.dproj"/>
+		</Target>
+		<Target Name="Demo_Spring_MultipleImplementations:Clean">
+			<MSBuild Projects="..\..\DelphiSpring\Samples\SpringDemos\Demo.DependencyInjection\MultipleImplementations\Demo.Spring.MultipleImplementations.dproj" Targets="Clean"/>
+		</Target>
+		<Target Name="Demo_Spring_MultipleImplementations:Make">
+			<MSBuild Projects="..\..\DelphiSpring\Samples\SpringDemos\Demo.DependencyInjection\MultipleImplementations\Demo.Spring.MultipleImplementations.dproj" Targets="Make"/>
+		</Target>
 		<Target Name="Build">
-			<CallTarget Targets="Demo_Spring_ObjectContainer;Demo_Spring_SimpleInjection;Demo_Spring_FieldInjection;Demo_Spring_ConstructorInjection;Demo_Spring_PropertyInjection;Demo_Spring_Collections_Stack;Demo_Spring_Predicates;Demo_Spring_Nullable;Demo_Spring_Enum;Demo_Spring_ObserverPattern;Demo_Spring_FactoryPattern;Demo_Spring_Enumerators;Demo_Spring_Logging;Demo_Spring_DependencyInjection"/>
+			<CallTarget Targets="Demo_Spring_ObjectContainer;Demo_Spring_SimpleInjection;Demo_Spring_FieldInjection;Demo_Spring_ConstructorInjection;Demo_Spring_PropertyInjection;Demo_Spring_Collections_Stack;Demo_Spring_Predicates;Demo_Spring_Nullable;Demo_Spring_Enum;Demo_Spring_ObserverPattern;Demo_Spring_FactoryPattern;Demo_Spring_Enumerators;Demo_Spring_Logging;Demo_Spring_DependencyInjection;Demo_Spring_MultipleImplementations"/>
 		</Target>
 		<Target Name="Clean">
-			<CallTarget Targets="Demo_Spring_ObjectContainer:Clean;Demo_Spring_SimpleInjection:Clean;Demo_Spring_FieldInjection:Clean;Demo_Spring_ConstructorInjection:Clean;Demo_Spring_PropertyInjection:Clean;Demo_Spring_Collections_Stack:Clean;Demo_Spring_Predicates:Clean;Demo_Spring_Nullable:Clean;Demo_Spring_Enum:Clean;Demo_Spring_ObserverPattern:Clean;Demo_Spring_FactoryPattern:Clean;Demo_Spring_Enumerators:Clean;Demo_Spring_Logging:Clean;Demo_Spring_DependencyInjection:Clean"/>
+			<CallTarget Targets="Demo_Spring_ObjectContainer:Clean;Demo_Spring_SimpleInjection:Clean;Demo_Spring_FieldInjection:Clean;Demo_Spring_ConstructorInjection:Clean;Demo_Spring_PropertyInjection:Clean;Demo_Spring_Collections_Stack:Clean;Demo_Spring_Predicates:Clean;Demo_Spring_Nullable:Clean;Demo_Spring_Enum:Clean;Demo_Spring_ObserverPattern:Clean;Demo_Spring_FactoryPattern:Clean;Demo_Spring_Enumerators:Clean;Demo_Spring_Logging:Clean;Demo_Spring_DependencyInjection:Clean;Demo_Spring_MultipleImplementations:Clean"/>
 		</Target>
 		<Target Name="Make">
-			<CallTarget Targets="Demo_Spring_ObjectContainer:Make;Demo_Spring_SimpleInjection:Make;Demo_Spring_FieldInjection:Make;Demo_Spring_ConstructorInjection:Make;Demo_Spring_PropertyInjection:Make;Demo_Spring_Collections_Stack:Make;Demo_Spring_Predicates:Make;Demo_Spring_Nullable:Make;Demo_Spring_Enum:Make;Demo_Spring_ObserverPattern:Make;Demo_Spring_FactoryPattern:Make;Demo_Spring_Enumerators:Make;Demo_Spring_Logging:Make;Demo_Spring_DependencyInjection:Make"/>
+			<CallTarget Targets="Demo_Spring_ObjectContainer:Make;Demo_Spring_SimpleInjection:Make;Demo_Spring_FieldInjection:Make;Demo_Spring_ConstructorInjection:Make;Demo_Spring_PropertyInjection:Make;Demo_Spring_Collections_Stack:Make;Demo_Spring_Predicates:Make;Demo_Spring_Nullable:Make;Demo_Spring_Enum:Make;Demo_Spring_ObserverPattern:Make;Demo_Spring_FactoryPattern:Make;Demo_Spring_Enumerators:Make;Demo_Spring_Logging:Make;Demo_Spring_DependencyInjection:Make;Demo_Spring_MultipleImplementations:Make"/>
 		</Target>
 		<Import Condition="Exists('$(BDS)\Bin\CodeGear.Group.Targets')" Project="$(BDS)\Bin\CodeGear.Group.Targets"/>
 	</Project>

UnitTesting/Calculator/CalculatorTestUnit.pas

   TestFramework, uCalculator;
 
 type
-  // Test methods for class TMyClass
+  // Test methods for class TCalculator
 
+//  TestTCalculator = class(TTestCase)
+//  strict private
+//    TempCalc: TCalculator;
+//  private
+//    function AddNumbers(const A, B: integer): integer;
+//  public
+//    procedure SetUp; override;
+//    procedure TearDown; override;
+//  published
+//    // This is where the test methods go
+//    procedure TestAddition;
+//    procedure TestWithData;
+//  end;
+
+
+
+//
   TestTCalculator = class(TTestCase)
   strict private
     TempCalc: TCalculator;
   private
-    function AddNumbers(A, B: integer): integer;
-    function SubtractNumbers(A, B: integer): integer;
+    function AddNumbers(const A, B: integer): integer;
+    function SubtractNumbers(const A, B: integer): integer;
   public
     procedure SetUp; override;
     procedure TearDown; override;
   published
     // This is where the test methods go
-    procedure TestPressEquals;
- //   procedure TestWithData;
+    procedure TestAddition;
+    procedure TestWithData;
     procedure TestSubtraction;
   end;
 
+
+
 implementation
 
 uses SysUtils;
   TempCalc := nil;
 end;
 
-{ TODO -oNick -cGeneral : Refactor to use expected, actual }
-{ TODO -oNick -cGeneral : Make it a general function to limit duplicated code }
-
-procedure TestTCalculator.TestPressEquals;
-var
-  TestResult, ExpectedResult: integer;
-begin
-  TestResult := AddNumbers(2, 3);
-  ExpectedResult := 5;
-
-  CheckEquals(ExpectedResult, TestResult);
-
-  TestResult := AddNumbers(-1, 3);
-  ExpectedResult := 2;
-
-  CheckEquals(ExpectedResult, TestResult);
-
-  TestResult := AddNumbers(-10, 3);
-  ExpectedResult := -7;
-
-  CheckEquals(ExpectedResult, TestResult);
-
-  TestResult := AddNumbers(-10, -3);
-  ExpectedResult := -13;
-
-  CheckEquals(ExpectedResult, TestResult);
-
-
-end;
-
-function TestTCalculator.SubtractNumbers(A, B: integer): integer;
-begin
-  TempCalc.Clear;
-  TempCalc.Enter(A);
-  TempCalc.PressSubtract;
-  TempCalc.Enter(B);
-  TempCalc.PressEquals;
-  Result := TempCalc.Display;
-end;
-
-function TestTCalculator.AddNumbers(A, B: integer): integer;
+function TestTCalculator.AddNumbers(const A, B: integer): integer;
 begin
   TempCalc.Clear;
   TempCalc.Enter(A);
   Result := TempCalc.Display;
 end;
 
+procedure TestTCalculator.TestAddition;
+var
+  TestResult, ExpectedResult: integer;
+begin
+  TestResult := AddNumbers(2, 3);
+  ExpectedResult := 5;
+  CheckEquals(ExpectedResult, TestResult);
+
+
+  TestResult := AddNumbers(-1, 3);
+  ExpectedResult := 2;
+  CheckEquals(ExpectedResult, TestResult);
+
+  TestResult := AddNumbers(-10, 3);