Index: src/NAnt.Core/FrameworkInfo.cs
===================================================================
RCS file: /cvsroot/nant/nant/src/NAnt.Core/FrameworkInfo.cs,v
retrieving revision 1.33
diff -u -r1.33 FrameworkInfo.cs
--- src/NAnt.Core/FrameworkInfo.cs	10 May 2009 13:19:15 -0000	1.33
+++ src/NAnt.Core/FrameworkInfo.cs	15 Jun 2009 16:16:13 -0000
@@ -54,6 +54,7 @@
         private Project _project;
         private FileSet _taskAssemblies;
         private FileSet[] _referenceAssemblies;
+		private readonly object _referenceAssembliesSyncRoot = new object();
         private string[] _toolPaths;
         private InitStatus _status = InitStatus.Uninitialized;
 
@@ -508,22 +509,23 @@
                 // ensure we're not dealing with an invalid framework
                 AssertNotInvalid();
 
-                if (_referenceAssemblies == null) {
-                    // reference assemblies
-                    XmlNodeList referenceAssemblies = _frameworkNode.SelectNodes(
-                        "nant:reference-assemblies", NamespaceManager);
-                    _referenceAssemblies = new FileSet [referenceAssemblies.Count];
-                    for (int i = 0; i < referenceAssemblies.Count; i++) {
-                        XmlNode node = referenceAssemblies [i];
-                        FileSet fileset = new FileSet();
-                        fileset.Project = Project;
-                        fileset.NamespaceManager = NamespaceManager;
-                        fileset.Parent = Project;
-                        fileset.ID = "reference-assemblies-" + i.ToString (CultureInfo.InvariantCulture);
-                        fileset.Initialize(node, Project.Properties, this);
-                        _referenceAssemblies [i] = fileset;
-                    }
-                }
+				lock(_referenceAssembliesSyncRoot)
+					if (_referenceAssemblies == null) {
+						// reference assemblies
+						XmlNodeList referenceAssemblies = _frameworkNode.SelectNodes(
+							"nant:reference-assemblies", NamespaceManager);
+						_referenceAssemblies = new FileSet [referenceAssemblies.Count];
+						for (int i = 0; i < referenceAssemblies.Count; i++) {
+							XmlNode node = referenceAssemblies [i];
+							FileSet fileset = new FileSet();
+							fileset.Project = Project;
+							fileset.NamespaceManager = NamespaceManager;
+							fileset.Parent = Project;
+							fileset.ID = "reference-assemblies-" + i.ToString (CultureInfo.InvariantCulture);
+							fileset.Initialize(node, Project.Properties, this);
+							_referenceAssemblies [i] = fileset;
+						}
+					}
                 return _referenceAssemblies;
             }
         }
Index: src/NAnt.Core/DirectoryScanner.cs
===================================================================
RCS file: /cvsroot/nant/nant/src/NAnt.Core/DirectoryScanner.cs,v
retrieving revision 1.58
diff -u -r1.58 DirectoryScanner.cs
--- src/NAnt.Core/DirectoryScanner.cs	25 Apr 2009 13:38:26 -0000	1.58
+++ src/NAnt.Core/DirectoryScanner.cs	15 Jun 2009 16:16:10 -0000
@@ -124,6 +124,8 @@
         private ArrayList _searchDirIsRecursive;
         private bool _caseSensitive;
 
+		private readonly object syncRoot = new object();
+
         #endregion Private Instance Fields
 
         #region Private Static Fields
@@ -223,10 +225,14 @@
         public bool CaseSensitive {
             get { return _caseSensitive; }
             set {
-                if (value != _caseSensitive) {
-                    _caseSensitive = value;
-                    Reset ();
-                }
+				lock (syncRoot)
+				{
+					if (value != _caseSensitive)
+					{
+						_caseSensitive = value;
+						Reset();
+					}
+				}
             }
         }
 
@@ -249,25 +255,34 @@
         /// <see cref="Environment.CurrentDirectory">current directory</see>.
         /// </summary>
         public DirectoryInfo BaseDirectory {
-            get { 
-                if (_baseDirectory == null) {
-                    _baseDirectory = new DirectoryInfo(CleanPath(
-                        Environment.CurrentDirectory).ToString());
-                }
-                return _baseDirectory;
-            }
-            set { 
-                if (value != null) {
-                    // convert both slashes and backslashes to directory separator
-                    // char
-                    value = new DirectoryInfo(CleanPath(
-                        value.FullName).ToString());
-                }
-
-                if (value != _baseDirectory) {
-                    _baseDirectory = value;
-                    Reset ();
-                }
+            get {
+				lock (syncRoot)
+				{
+					if (_baseDirectory == null)
+					{
+						_baseDirectory = new DirectoryInfo(CleanPath(
+						                                   	Environment.CurrentDirectory).ToString());
+					}
+					return _baseDirectory;
+				}
+            }
+            set {
+				lock (syncRoot)
+				{
+					if (value != null)
+					{
+						// convert both slashes and backslashes to directory separator
+						// char
+						value = new DirectoryInfo(CleanPath(
+						                          	value.FullName).ToString());
+					}
+
+					if (value != _baseDirectory)
+					{
+						_baseDirectory = value;
+						Reset();
+					}
+				}
             }
         }
 
@@ -276,10 +291,14 @@
         /// </summary>
         public StringCollection FileNames {
             get {
-                if (_fileNames == null) {
-                    Scan();
-                }
-                return _fileNames;
+				lock (syncRoot)
+				{
+					if (_fileNames == null)
+					{
+						Scan();
+					}
+					return _fileNames;
+				}
             }
         }
 
@@ -288,10 +307,14 @@
         /// </summary>
         public StringCollection DirectoryNames {
             get {
-                if (_directoryNames == null) {
-                    Scan();
-                }
-                return _directoryNames;
+				lock (syncRoot)
+				{
+					if (_directoryNames == null)
+					{
+						Scan();
+					}
+					return _directoryNames;
+				}
             }
         }
 
@@ -300,10 +323,14 @@
         /// </summary>
         public StringCollection ScannedDirectories {
             get {
-                if (_scannedDirectories == null) {
-                    Scan();
-                }
-                return _scannedDirectories;
+				lock (syncRoot)
+				{
+					if (_scannedDirectories == null)
+					{
+						Scan();
+					}
+					return _scannedDirectories;
+				}
             }
         }
 
@@ -316,16 +343,18 @@
         /// <see cref="BaseDirectory" /> or absolute), to search for filesystem objects.
         /// </summary>
         public void Scan() {
-            _includePatterns = new ArrayList();
-            _includeNames = new StringCollectionWithGoodToString ();
-            _excludePatterns = new ArrayList();
-            _excludeNames = new StringCollectionWithGoodToString ();
-            _fileNames = new StringCollectionWithGoodToString ();
-            _directoryNames = new DirScannerStringCollection(CaseSensitive);
-
-            _searchDirectories = new DirScannerStringCollection(CaseSensitive);
-            _searchDirIsRecursive = new ArrayList();
-            _scannedDirectories = new DirScannerStringCollection(CaseSensitive);
+			lock (syncRoot)
+			{
+				_includePatterns = new ArrayList();
+				_includeNames = new StringCollectionWithGoodToString();
+				_excludePatterns = new ArrayList();
+				_excludeNames = new StringCollectionWithGoodToString();
+				_fileNames = new StringCollectionWithGoodToString();
+				_directoryNames = new DirScannerStringCollection(CaseSensitive);
+
+				_searchDirectories = new DirScannerStringCollection(CaseSensitive);
+				_searchDirIsRecursive = new ArrayList();
+				_scannedDirectories = new DirScannerStringCollection(CaseSensitive);
 
 #if DEBUG_REGEXES
             Console.WriteLine("*********************************************************************");
@@ -345,18 +374,20 @@
             Console.WriteLine("--- Starting Scan ---");
 #endif
 
-            // convert given NAnt patterns to regex patterns with absolute paths
-            // side effect: searchDirectories will be populated
-            ConvertPatterns(_includes, _includePatterns, _includeNames, true);
-            ConvertPatterns(_excludes, _excludePatterns, _excludeNames, false);
+				// convert given NAnt patterns to regex patterns with absolute paths
+				// side effect: searchDirectories will be populated
+				ConvertPatterns(_includes, _includePatterns, _includeNames, true);
+				ConvertPatterns(_excludes, _excludePatterns, _excludeNames, false);
+
+				for (int index = 0; index < _searchDirectories.Count; index++)
+				{
+					ScanDirectory(_searchDirectories[index], (bool) _searchDirIsRecursive[index]);
+				}
 
-            for (int index = 0; index < _searchDirectories.Count; index++) {
-                ScanDirectory(_searchDirectories[index], (bool) _searchDirIsRecursive[index]);
-            }
-            
 #if DEBUG_REGEXES
             Console.WriteLine("*********************************************************************");
 #endif
+			}
         }
 
         #endregion Public Instance Methods
Index: src/NAnt.Core/Project.cs
===================================================================
RCS file: /cvsroot/nant/nant/src/NAnt.Core/Project.cs,v
retrieving revision 1.95
diff -u -r1.95 Project.cs
--- src/NAnt.Core/Project.cs	10 May 2009 13:45:50 -0000	1.95
+++ src/NAnt.Core/Project.cs	15 Jun 2009 16:16:14 -0000
@@ -22,17 +22,15 @@
 
 using System;
 using System.Collections;
+using System.Collections.Generic;
 using System.Collections.Specialized;
-using System.ComponentModel;
 using System.Configuration;
 using System.Globalization;
 using System.IO;
 using System.Reflection;
 using System.Text;
+using System.Threading;
 using System.Xml;
-
-using Microsoft.Win32;
-
 using NAnt.Core.Tasks;
 using NAnt.Core.Util;
 
@@ -118,6 +116,7 @@
         public event BuildEventHandler BuildFinished;
         public event BuildEventHandler TargetStarted;
         public event BuildEventHandler TargetFinished;
+		public event BuildEventHandler TargetExecuted;
         public event BuildEventHandler TaskStarted;
         public event BuildEventHandler TaskFinished;
         public event BuildEventHandler MessageLogged;
@@ -152,6 +151,20 @@
         private XmlNamespaceManager _nsMgr = new XmlNamespaceManager(new NameTable()); //used to map "nant" to default namespace.
         [NonSerialized()]
         private DataTypeBaseDictionary _dataTypeReferences = new DataTypeBaseDictionary();
+		[NonSerialized()]
+		private readonly Dictionary<string, ManualResetEvent> targetExecuted
+			= new Dictionary<string,ManualResetEvent>();
+		[NonSerialized()]
+		private readonly ManualResetEvent workerFinished = new ManualResetEvent(false);
+		[NonSerialized()]
+		private readonly object activeThreadCountSyncRoot = new object();
+		[NonSerialized()]
+		private volatile int activeThreadCount;
+		[NonSerialized()]
+		private volatile int workerId;
+		// placeholder for exceptions in worker threads;
+		[NonSerialized()]
+		private volatile Exception workerThreadException;
 
         /// <summary>
         /// Holds the default threshold for build loggers.
@@ -170,7 +183,7 @@
         /// <param name="threshold">The message threshold.</param>
         /// <param name="indentLevel">The project indentation level.</param>
         public Project(XmlDocument doc, Level threshold, int indentLevel) {
-            // use NAnt settings from application configuration file for loading 
+        	// use NAnt settings from application configuration file for loading 
             // internal configuration settings
             _configurationNode = GetConfigurationNode();
 
@@ -193,7 +206,7 @@
         /// library.
         /// </remarks>
         public Project(XmlDocument doc, Level threshold, int indentLevel, XmlNode configurationNode) {
-            // set configuration node to use for loading internal configuration 
+        	// set configuration node to use for loading internal configuration 
             // settings
             _configurationNode = configurationNode;
 
@@ -215,7 +228,7 @@
         /// If the source is a uri of form 'file:///path' then use the path part.
         /// </remarks>
         public Project(string uriOrFilePath, Level threshold, int indentLevel) {
-            // use NAnt settings from application configuration file for loading 
+        	// use NAnt settings from application configuration file for loading 
             // internal configuration settings
             _configurationNode = GetConfigurationNode();
 
@@ -242,7 +255,7 @@
         /// If the source is a uri of form 'file:///path' then use the path part.
         /// </remarks>
         public Project(string uriOrFilePath, Level threshold, int indentLevel, XmlNode configurationNode) {
-            // set configuration node to use for loading internal configuration 
+        	// set configuration node to use for loading internal configuration 
             // settings
             _configurationNode = configurationNode;
 
@@ -269,7 +282,7 @@
         /// discovery of extension assemblies and framework configuration.
         /// </remarks>
         internal Project(string uriOrFilePath, Project parent) {
-            // set configuration node to use for loading internal configuration 
+        	// set configuration node to use for loading internal configuration 
             // settings
             _configurationNode = parent.ConfigurationNode;
 
@@ -304,13 +317,14 @@
         /// Optimized for framework initialization projects, by skipping automatic
         /// discovery of extension assemblies and framework configuration.
         /// </remarks>
-        internal Project(XmlDocument doc) {
-            // initialize project
+        internal Project(XmlDocument doc)
+        {
+        	// initialize project
             CtorHelper(doc, Level.None, 0, Optimizations.SkipAutomaticDiscovery |
                 Optimizations.SkipFrameworkConfiguration);
         }
-    
-        #endregion Internal Instance Constructors
+
+    	#endregion Internal Instance Constructors
 
         #region Public Instance Properties
 
@@ -844,10 +858,32 @@
         /// <param name="sender">The source of the event.</param>
         /// <param name="e">A <see cref="BuildEventArgs" /> that contains the event data.</param>
         public void OnTargetFinished(object sender, BuildEventArgs e) {
-            if (TargetFinished != null) {
-                TargetFinished(sender, e);
+        	BuildEventHandler targetFinishedHandler = TargetFinished;
+			if (targetFinishedHandler != null)
+			{
+				targetFinishedHandler(sender, e);
             }
         }
+
+		/// <summary>
+		/// Dispatches a <see cref="TargetExecuted" /> event to the build listeners 
+		/// for this <see cref="Project" />.
+		/// </summary>
+		/// <param name="sender">The source of the event.</param>
+		/// <param name="e">A <see cref="BuildEventArgs" /> that contains the event data.</param>
+		public void OnTargetExecuted(object sender, BuildEventArgs e)
+		{
+			BuildEventHandler targetExecutedHandler = TargetExecuted;
+			if (targetExecutedHandler != null)
+			{
+				targetExecutedHandler(sender, e);
+				if (e.Target != null)
+					lock (targetExecuted)
+						if (targetExecuted.ContainsKey(e.Target.Name))
+							targetExecuted[e.Target.Name].Set();
+			}
+		}
+
         /// <summary>
         /// Dispatches a <see cref="TaskStarted" /> event to the build listeners 
         /// for this <see cref="Project" />.
@@ -1018,6 +1054,12 @@
             // store calling target
             Target callingTarget = _currentTarget;
 
+			lock(targetExecuted)
+			{
+				if(!targetExecuted.ContainsKey(targetName))
+					targetExecuted.Add(targetName, new ManualResetEvent(false));
+			}
+
             do {
                 // determine target that should be executed
                 currentTarget = (Target) sortedTargets[currentIndex++];
@@ -1028,18 +1070,72 @@
                 // only execute targets that have not been executed already, if 
                 // we are not forcing.
                 if (forceDependencies || !currentTarget.Executed || currentTarget.Name == targetName) {
-                    currentTarget.Execute();
+					while (true)
+                	{
+						//break as soon as possible
+						CheckPendingExceptions();
+						if (currentTarget.DependenciesAlreadyExecuted)
+						{
+							lock (activeThreadCountSyncRoot)
+							{
+								if (activeThreadCount < Environment.ProcessorCount * 2)
+								{
+									Thread worker = new Thread((target) => 
+										{
+											try
+											{
+												((Target) target).Execute();
+											}
+											catch (Exception ex)
+											{
+												workerThreadException = ex;
+											}
+											lock (activeThreadCountSyncRoot)
+												activeThreadCount--;
+											workerFinished.Set();
+										});
+									worker.Name = String.Format("[W{0}] {1}", workerId++, currentTarget.Name);
+									worker.Start(currentTarget);
+									activeThreadCount++;
+									break;
+								}
+							}
+							// no worker threads available, execute on MainThread
+							currentTarget.Execute();
+							break;
+						}
+                		// TODO: in theory, the timeout here is not needed if we don't deadlock
+                		workerFinished.WaitOne();
+                	}
                 }
             } while (currentTarget.Name != targetName);
 
-            // restore calling target, as a <call> task might have caused the 
+			//wait until targetName target has executed ('while loop' finishes when targetName has been scheduled)
+        	targetExecuted[targetName].WaitOne();
+
+			CheckPendingExceptions();
+
+        	// restore calling target, as a <call> task might have caused the 
             // current target to be executed and when finished executing this 
             // target, the target that contained the <call> task should be 
             // considered the current target again
             _currentTarget = callingTarget;
         }
 
-        /// <summary>
+    	private void CheckPendingExceptions()
+    	{
+    		if (workerThreadException != null)
+    		{
+    			Exception exception =
+    				(Exception) Activator.CreateInstance(
+    				            	workerThreadException.GetType(),
+    				            	workerThreadException.Message,
+    				            	workerThreadException);
+    			throw exception;
+    		}
+    	}
+
+    	/// <summary>
         /// Executes the default target and wraps in error handling and time 
         /// stamping.
         /// </summary>
Index: src/NAnt.Core/Target.cs
===================================================================
RCS file: /cvsroot/nant/nant/src/NAnt.Core/Target.cs,v
retrieving revision 1.27
diff -u -r1.27 Target.cs
--- src/NAnt.Core/Target.cs	15 Dec 2007 21:33:00 -0000	1.27
+++ src/NAnt.Core/Target.cs	15 Jun 2009 16:16:14 -0000
@@ -21,6 +21,7 @@
 // William E. Caputo (wecaputo@thoughtworks.com | logosity@yahoo.com)
 
 using System;
+using System.Collections.Generic;
 using System.Collections.Specialized;
 using System.Globalization;
 using System.Xml;
@@ -39,6 +40,7 @@
         private string _unlessCondition;
         private StringCollection _dependencies = new StringCollection();
         private bool _executed;
+		private Dictionary<string, object> _unexecutedDependenciesSet = new Dictionary<string,object>();
 
         #endregion Private Instance Fields
 
@@ -178,6 +180,7 @@
                     string dependency = str.Trim();
                     if (dependency.Length > 0) {
                         Dependencies.Add(dependency);
+						_unexecutedDependenciesSet.Add(dependency, this);
                     }
                 }
             }
@@ -191,6 +194,36 @@
             get { return _dependencies; }
         }
 
+		public override Project Project
+		{
+			get
+			{
+				return base.Project;
+			}
+			set
+			{
+				base.Project = value;
+				base.Project.TargetExecuted += (sender, e) =>
+				{
+					if (e.Target != null)
+						lock (_unexecutedDependenciesSet)
+						{
+							if (_unexecutedDependenciesSet.ContainsKey(e.Target.Name))
+								_unexecutedDependenciesSet.Remove(e.Target.Name);
+						}
+				};
+			}
+		}
+
+    	public bool DependenciesAlreadyExecuted
+    	{
+    		get
+    		{
+				lock (_unexecutedDependenciesSet)
+					return _unexecutedDependenciesSet.Count == 0;
+    		}
+    	}
+
         #endregion Public Instance Properties
 
         #region Implementation of ICloneable
@@ -231,41 +264,64 @@
         /// Executes dependent targets first, then the target.
         /// </summary>
         public void Execute() {
-            if (IfDefined && !UnlessDefined) {
-                try {
-                    Project.OnTargetStarted(this, new BuildEventArgs(this));
-                
-                    // select all the task nodes and execute them
-                    foreach (XmlNode childNode in XmlNode) {
-                        if (!(childNode.NodeType == XmlNodeType.Element)|| !childNode.NamespaceURI.Equals(NamespaceManager.LookupNamespace("nant"))) {
-                            continue;
-                        }
-                        
-                        if (TypeFactory.TaskBuilders.Contains(childNode.Name)) {
-                            Task task = Project.CreateTask(childNode, this);
-                            if (task != null) {
-                                task.Execute();
-                            }
-                        } else if (TypeFactory.DataTypeBuilders.Contains(childNode.Name)) {
-                            DataTypeBase dataType = Project.CreateDataTypeBase(childNode);
-                            Project.Log(Level.Verbose, "Adding a {0} reference with id '{1}'.", 
-                                childNode.Name, dataType.ID);
-                            if (!Project.DataTypeReferences.Contains(dataType.ID)) {
-                                Project.DataTypeReferences.Add(dataType.ID, dataType);
-                            } else {
-                                Project.DataTypeReferences[dataType.ID] = dataType; // overwrite with the new reference.
-                            }
-                        } else {
-                            throw new BuildException(string.Format(CultureInfo.InvariantCulture, 
-                                ResourceUtils.GetString("NA1071"), 
-                                childNode.Name), Project.LocationMap.GetLocation(childNode));
-                        }
-                    }
-                } finally {
-                    _executed = true;
-                    Project.OnTargetFinished(this, new BuildEventArgs(this));
-                }
-            }
+			try
+			{
+				if (IfDefined && !UnlessDefined)
+				{
+					try
+					{
+						Project.OnTargetStarted(this, new BuildEventArgs(this));
+
+						// select all the task nodes and execute them
+						foreach (XmlNode childNode in XmlNode)
+						{
+							if (!(childNode.NodeType == XmlNodeType.Element) ||
+								!childNode.NamespaceURI.Equals(NamespaceManager.LookupNamespace("nant")))
+							{
+								continue;
+							}
+
+							if (TypeFactory.TaskBuilders.Contains(childNode.Name))
+							{
+								Task task = Project.CreateTask(childNode, this);
+								if (task != null)
+								{
+									task.Execute();
+								}
+							}
+							else if (TypeFactory.DataTypeBuilders.Contains(childNode.Name))
+							{
+								DataTypeBase dataType = Project.CreateDataTypeBase(childNode);
+								Project.Log(Level.Verbose, "Adding a {0} reference with id '{1}'.",
+											childNode.Name, dataType.ID);
+								if (!Project.DataTypeReferences.Contains(dataType.ID))
+								{
+									Project.DataTypeReferences.Add(dataType.ID, dataType);
+								}
+								else
+								{
+									Project.DataTypeReferences[dataType.ID] = dataType; // overwrite with the new reference.
+								}
+							}
+							else
+							{
+								throw new BuildException(string.Format(CultureInfo.InvariantCulture,
+																	   ResourceUtils.GetString("NA1071"),
+																	   childNode.Name), Project.LocationMap.GetLocation(childNode));
+							}
+						}
+					}
+					finally
+					{
+						_executed = true;
+						Project.OnTargetFinished(this, new BuildEventArgs(this));
+					}
+				}
+			}
+			finally
+			{
+				Project.OnTargetExecuted(this, new BuildEventArgs(this));
+			}
         }
 
         #endregion Public Instance Methods
Index: src/NAnt.Core/Element.cs
===================================================================
RCS file: /cvsroot/nant/nant/src/NAnt.Core/Element.cs,v
retrieving revision 1.97
diff -u -r1.97 Element.cs
--- src/NAnt.Core/Element.cs	15 Dec 2007 21:37:11 -0000	1.97
+++ src/NAnt.Core/Element.cs	15 Jun 2009 16:16:12 -0000
@@ -1454,33 +1454,51 @@
             /// An <see cref="IAttributeSetter" /> for the given <see cref="Type" />.
             /// </returns>
             private IAttributeSetter CreateAttributeSetter(Type attributeType) {
-                if (AttributeSetters.ContainsKey(attributeType)) {
-                    return (IAttributeSetter) AttributeSetters[attributeType];
-                }
-
-                IAttributeSetter attributeSetter = null;
-
-                if (attributeType.IsEnum) {
-                    attributeSetter = new EnumAttributeSetter();
-                } else if (attributeType == typeof(Encoding)) {
-                    attributeSetter = new EncodingAttributeSetter();
-                } else if (attributeType == typeof(FileInfo)) {
-                    attributeSetter = new FileAttributeSetter();
-                } else if (attributeType == typeof(DirectoryInfo)) {
-                    attributeSetter = new DirectoryAttributeSetter();
-                } else if (attributeType == typeof(PathSet)) {
-                    attributeSetter = new PathSetAttributeSetter();
-                } else if (attributeType == typeof(Uri)) {
-                    attributeSetter = new UriAttributeSetter();
-                } else {
-                    attributeSetter = new ConvertableAttributeSetter();
-                }
-
-                if (attributeSetter != null) {
-                    AttributeSetters.Add(attributeType, attributeSetter);
-                }
+				lock (AttributeSetters.SyncRoot)
+				{
+					if (AttributeSetters.ContainsKey(attributeType))
+					{
+						return (IAttributeSetter) AttributeSetters[attributeType];
+					}
+
+					IAttributeSetter attributeSetter = null;
+
+					if (attributeType.IsEnum)
+					{
+						attributeSetter = new EnumAttributeSetter();
+					}
+					else if (attributeType == typeof (Encoding))
+					{
+						attributeSetter = new EncodingAttributeSetter();
+					}
+					else if (attributeType == typeof (FileInfo))
+					{
+						attributeSetter = new FileAttributeSetter();
+					}
+					else if (attributeType == typeof (DirectoryInfo))
+					{
+						attributeSetter = new DirectoryAttributeSetter();
+					}
+					else if (attributeType == typeof (PathSet))
+					{
+						attributeSetter = new PathSetAttributeSetter();
+					}
+					else if (attributeType == typeof (Uri))
+					{
+						attributeSetter = new UriAttributeSetter();
+					}
+					else
+					{
+						attributeSetter = new ConvertableAttributeSetter();
+					}
+
+					if (attributeSetter != null)
+					{
+						AttributeSetters.Add(attributeType, attributeSetter);
+					}
 
-                return attributeSetter;
+					return attributeSetter;
+				}
             }
 
             #endregion Private Instance Methods
Index: src/NAnt.Core/Util/ResourceUtils.cs
===================================================================
RCS file: /cvsroot/nant/nant/src/NAnt.Core/Util/ResourceUtils.cs,v
retrieving revision 1.9
diff -u -r1.9 ResourceUtils.cs
--- src/NAnt.Core/Util/ResourceUtils.cs	21 May 2005 16:43:48 -0000	1.9
+++ src/NAnt.Core/Util/ResourceUtils.cs	15 Jun 2009 16:16:14 -0000
@@ -172,29 +172,35 @@
         /// ]]>
         /// </code>
         /// </example>
-        public static string GetString(string name, CultureInfo culture, Assembly assembly) {
-            string assemblyName = assembly.GetName().Name;
-
-            if (!_resourceManagerDictionary.Contains(assemblyName)) {
-                RegisterAssembly(assembly);
-            }
-
-            // retrieve resource manager for assembly
-            ResourceManager resourceManager = (ResourceManager) 
-                _resourceManagerDictionary[assemblyName];
-
-            // try to get the required string from the given assembly
-            string localizedString = resourceManager.GetString(name, culture);
-
-            // if the given assembly does not contain the required string, then
-            // try to get it from the shared satellite assembly, if registered
-            if (localizedString == null && _sharedResourceManager != null) {
-                return _sharedResourceManager.GetString(name, culture);
-            }
-            return localizedString;
+		public static string GetString(string name, CultureInfo culture, Assembly assembly)
+        {
+        	string assemblyName = assembly.GetName().Name;
+        	ResourceManager resourceManager;
+
+        	lock (_resourceManagerDictionary.SyncRoot)
+        	{
+        		if (!_resourceManagerDictionary.Contains(assemblyName))
+        		{
+        			RegisterAssembly(assembly);
+        		}
+
+        		// retrieve resource manager for assembly
+        		resourceManager = (ResourceManager) _resourceManagerDictionary[assemblyName];
+        	}
+
+        	// try to get the required string from the given assembly
+        	string localizedString = resourceManager.GetString(name, culture);
+
+        	// if the given assembly does not contain the required string, then
+        	// try to get it from the shared satellite assembly, if registered
+        	if (localizedString == null && _sharedResourceManager != null)
+        	{
+        		return _sharedResourceManager.GetString(name, culture);
+        	}
+        	return localizedString;
         }
 
-        #endregion Public Static Methods
+    	#endregion Public Static Methods
 
         #region Private Static Methods
 
@@ -205,17 +211,16 @@
         /// A <see cref="System.Reflection.Assembly" /> that represents the
         /// assembly to register.
         /// </param>
-        private static void RegisterAssembly(Assembly assembly) {
-            lock (_resourceManagerDictionary) {
-                string assemblyName = assembly.GetName().Name;
-
-                _resourceManagerDictionary.Add(assemblyName,
-                    new ResourceManager(GetResourceName(assemblyName), 
-                    assembly));
-            }
+		private static void RegisterAssembly(Assembly assembly)
+        {
+        	string assemblyName = assembly.GetName().Name;
+
+        	_resourceManagerDictionary.Add(assemblyName,
+        	                               new ResourceManager(GetResourceName(assemblyName),
+        	                                                   assembly));
         }
 
-        /// <summary>
+    	/// <summary>
         /// Determines the manifest resource name of the resource holding the
         /// localized strings.
         /// </summary>
