diff --git a/nant.build b/nant.build
index 9a66023..ae3b149 100644
--- a/nant.build
+++ b/nant.build
@@ -88,6 +88,7 @@
             <include name="${current.build.framework.assembly.dir}/mscorlib.dll" />
             <include name="${current.build.framework.assembly.dir}/System.dll" />
             <include name="${current.build.framework.assembly.dir}/System.Xml.dll" />
+            <include name="${current.build.framework.assembly.dir}/System.Web.dll" />
             <include name="${build.bin.dir}/${project.name}.dll" />
             <include name="${nunit.dll}" />
         </assemblyfileset>
diff --git a/src/main/csharp/Util/URISupport.cs b/src/main/csharp/Util/URISupport.cs
index e17df5a..5a3d686 100644
--- a/src/main/csharp/Util/URISupport.cs
+++ b/src/main/csharp/Util/URISupport.cs
@@ -1,639 +1,638 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Collections.Specialized;
-using System.Globalization;
-using System.Reflection;
-using System.Text;
-#if !NETCF
-using System.Web;
-#endif
-
-namespace Apache.NMS.Util
-{
-	/// <summary>
-	/// Class to provide support for Uri query parameters which uses .Net reflection
-	/// to identify and set properties.
-	/// </summary>
-	public class URISupport
-	{
-		/// <summary>
-		/// Given a string that could be a Composite Uri that uses syntax not compatible
-		/// with the .NET Uri class such as an ActiveMQ failover Uri formatted as
-		/// "failover://(tcp://localhost:61616)", the initial '://' must be changed
-		/// to ':(' so that the Uri class doesn't attempt to parse the '(tcp:' as
-		/// the Uri's Authority as that is not a valid host name.
-		/// </summary>
-		/// <param name="uriString">
-		/// A string that could be a Composite Uri that uses syntax not compatible
-		/// with the .NET Uri class
-		/// </param>
-		public static Uri CreateCompatibleUri(string uriString)
-		{
-			string sanitized = uriString.Replace("://(", ":(");
-			return new Uri(sanitized);
-		}
-
-		/// <summary>
-		/// Parse a Uri query string of the form ?x=y&amp;z=0
-		/// into a map of name/value pairs.
-		/// </summary>
-		/// <param name="query">The query string to parse. This string should not contain
-		/// Uri escape characters.</param>
-		public static StringDictionary ParseQuery(String query)
-		{
-			StringDictionary map = new StringDictionary();
-
-			if(String.IsNullOrEmpty(query))
-			{
-				return EmptyMap;
-			}
-
-			// strip the initial "?"
-			if(query.StartsWith("?"))
-			{
-				query = query.Substring(1);
-			}
-
-			// split the query into parameters
-			string[] parameters = query.Split('&');
-			foreach(string pair in parameters)
-			{
-				if(pair.Length > 0)
-				{
-					string[] nameValue = pair.Split('=');
-
-					if(nameValue.Length != 2)
-					{
-						throw new NMSException(string.Format("Invalid Uri parameter: {0}", query));
-					}
-
-					map[nameValue[0]] = nameValue[1];
-				}
-			}
-
-			return map;
-		}
-
-		public static StringDictionary ParseParameters(Uri uri)
-		{
-			return (uri.Query == null
-					? EmptyMap
-					: ParseQuery(StripPrefix(uri.Query, "?")));
-		}
-
-		/// <summary>
-		/// Sets the public properties of a target object using a string map.
-		/// This method uses .Net reflection to identify public properties of
-		/// the target object matching the keys from the passed map.
-		/// </summary>
-		/// <param name="target">The object whose properties will be set.</param>
-		/// <param name="map">Map of key/value pairs.</param>
-		public static void SetProperties(object target, StringDictionary map)
-		{
-			Type type = target.GetType();
-
-			foreach(string key in map.Keys)
-			{
-				PropertyInfo prop = type.GetProperty(key,
-														BindingFlags.FlattenHierarchy
-														| BindingFlags.Public
-														| BindingFlags.Instance
-														| BindingFlags.IgnoreCase);
-
-				if(null != prop)
-				{
-					prop.SetValue(target, Convert.ChangeType(map[key], prop.PropertyType, CultureInfo.InvariantCulture), null);
-				}
-				else
-				{
-					FieldInfo field = type.GetField(key,
-														BindingFlags.FlattenHierarchy
-														| BindingFlags.Public
-														| BindingFlags.Instance
-														| BindingFlags.IgnoreCase);
-					if(null != field)
-					{
-						field.SetValue(target, Convert.ChangeType(map[key], field.FieldType, CultureInfo.InvariantCulture));
-					}
-					else
-					{
-						throw new NMSException(string.Format("No such property or field: {0} on class: {1}", key, target.GetType().Name));
-					}
-				}
-			}
-		}
-
-		/// <summary>
-		/// Sets the public properties of a target object using a string map.
-		/// This method uses .Net reflection to identify public properties of
-		/// the target object matching the keys from the passed map.
-		/// </summary>
-		/// <param name="target">The object whose properties will be set.</param>
-		/// <param name="map">Map of key/value pairs.</param>
-		/// <param name="prefix">Key value prefix.  This is prepended to the property name
-		/// before searching for a matching key value.</param>
-		public static void SetProperties(object target, StringDictionary map, string prefix)
-		{
-			Type type = target.GetType();
-
-			List<String> matches = new List<String>();
-
-			foreach(string key in map.Keys)
-			{
-				if(key.StartsWith(prefix, StringComparison.InvariantCultureIgnoreCase))
-				{
-					string bareKey = key.Substring(prefix.Length);
-					PropertyInfo prop = type.GetProperty(bareKey,
-															BindingFlags.FlattenHierarchy
-															| BindingFlags.Public
-															| BindingFlags.Instance
-															| BindingFlags.IgnoreCase);
-
-					if(null != prop)
-					{
-						prop.SetValue(target, Convert.ChangeType(map[key], prop.PropertyType, CultureInfo.InvariantCulture), null);
-					}
-					else
-					{
-						FieldInfo field = type.GetField(bareKey,
-															BindingFlags.FlattenHierarchy
-															| BindingFlags.Public
-															| BindingFlags.Instance
-															| BindingFlags.IgnoreCase);
-						if(null != field)
-						{
-							field.SetValue(target, Convert.ChangeType(map[key], field.FieldType, CultureInfo.InvariantCulture));
-						}
-						else
-						{
-							throw new NMSException(string.Format("No such property or field: {0} on class: {1}", bareKey, target.GetType().Name));
-						}
-					}
-
-					// store for later removal.
-					matches.Add(key);
-				}
-			}
-
-			// Remove all the properties we set so they are used again later.
-			foreach(string match in matches)
-			{
-				map.Remove(match);
-			}
-		}
-
-		public static StringDictionary GetProperties(StringDictionary props, string prefix)
-		{
-
-			if(props == null)
-			{
-				throw new Exception("Properties Object was null");
-			}
-
-			StringDictionary result = new StringDictionary();
-
-			foreach(string key in props.Keys)
-			{
-				if(key.StartsWith(prefix, StringComparison.InvariantCultureIgnoreCase))
-				{
-					string bareKey = key.Substring(prefix.Length);
-					String value = props[key];
-					result[bareKey] = value;
-				}
-			}
-
-			return result;
-		}
-
-		public static StringDictionary ExtractProperties(StringDictionary props, string prefix)
-		{
-
-			if(props == null)
-			{
-				throw new Exception("Properties Object was null");
-			}
-
-			StringDictionary result = new StringDictionary();
-			List<String> matches = new List<String>();
-
-			foreach(string key in props.Keys)
-			{
-				if(key.StartsWith(prefix, StringComparison.InvariantCultureIgnoreCase))
-				{
-					String value = props[key];
-					result[key] = value;
-					matches.Add(key);
-				}
-			}
-
-			foreach(string match in matches)
-			{
-				props.Remove(match);
-			}
-
-			return result;
-		}
-
-		public static String UrlDecode(String s)
-		{
-#if !NETCF
-			return HttpUtility.HtmlDecode(s);
-#else
-            return Uri.UnescapeDataString(s);
-#endif
-		}
-
-		public static String UrlEncode(String s)
-		{
-#if !NETCF
-			return HttpUtility.HtmlEncode(s);
-#else
-            return Uri.EscapeUriString(s);
-#endif
-		}
-
-		public static String CreateQueryString(StringDictionary options)
-		{
-			if(options != null && options.Count > 0)
-			{
-				StringBuilder rc = new StringBuilder();
-				bool first = true;
-
-				foreach(String key in options.Keys)
-				{
-					string value = options[key];
-
-					if(first)
-					{
-						first = false;
-					}
-					else
-					{
-						rc.Append("&");
-					}
-
-					rc.Append(UrlEncode(key));
-					rc.Append("=");
-					rc.Append(UrlEncode(value));
-				}
-
-				return rc.ToString();
-			}
-			else
-			{
-				return "";
-			}
-		}
-
-		public static Uri CreateRemainingUri(Uri originalUri, StringDictionary parameters)
-		{
-			string s = CreateQueryString(parameters);
-
-			if(String.IsNullOrEmpty(s))
-			{
-				s = null;
-			}
-
-			return CreateUriWithQuery(originalUri, s);
-		}
-
-		public class CompositeData
-		{
-			private String host;
-			private String scheme;
-			private String path;
-			private Uri[] components;
-			private StringDictionary parameters;
-			private String fragment;
-
-			public Uri[] Components
-			{
-				get { return components; }
-				set { components = value; }
-			}
-
-			public String Fragment
-			{
-				get { return fragment; }
-				set { fragment = value; }
-			}
-
-			public StringDictionary Parameters
-			{
-				get { return parameters; }
-				set { parameters = value; }
-			}
-
-			public String Scheme
-			{
-				get { return scheme; }
-				set { scheme = value; }
-			}
-
-			public String Path
-			{
-				get { return path; }
-				set { path = value; }
-			}
-
-			public String Host
-			{
-				get { return host; }
-				set { host = value; }
-			}
-
-			public Uri toUri()
-			{
-				StringBuilder sb = new StringBuilder();
-				if(scheme != null)
-				{
-					sb.Append(scheme);
-					sb.Append(':');
-				}
-
-				if(!string.IsNullOrEmpty(host))
-				{
-					sb.Append(host);
-				}
-				else
-				{
-					sb.Append('(');
-					for(int i = 0; i < components.Length; i++)
-					{
-						if(i != 0)
-						{
-							sb.Append(',');
-						}
-						sb.Append(components[i].ToString());
-					}
-					sb.Append(')');
-				}
-
-				if(path != null)
-				{
-					sb.Append('/');
-					sb.Append(path);
-				}
-
-				if(parameters.Count != 0)
-				{
-					sb.Append("?");
-					sb.Append(CreateQueryString(parameters));
-				}
-
-				if(fragment != null)
-				{
-					sb.Append("#");
-					sb.Append(fragment);
-				}
-
-				return new Uri(sb.ToString());
-			}
-		}
-
-		public static String StripPrefix(String value, String prefix)
-		{
-			if(value.StartsWith(prefix, StringComparison.InvariantCultureIgnoreCase))
-			{
-				return value.Substring(prefix.Length);
-			}
-
-			return value;
-		}
-
-		public static Uri CreateUriWithQuery(Uri uri, string query)
-		{
-			if(!String.IsNullOrEmpty(query) && !query.StartsWith("?"))
-			{
-				query = "?" + query;
-			}
-
-			if(String.IsNullOrEmpty(uri.Query))
-			{
-				return new Uri(uri.OriginalString + query);
-			}
-			else
-			{
-				string originalUri = uri.OriginalString;
-
-				int queryDelimPos = originalUri.LastIndexOf('?');
-				int compositeDelimPos = originalUri.LastIndexOf(')');
-
-				if(queryDelimPos <= compositeDelimPos)
-				{
-					// No Query or the Query is part of an inner Composite.
-					return new Uri(originalUri + query);
-				}
-				else
-				{
-					// Outer Uri has a Query or not a Composite Uri with a Query
-					string strippedUri = originalUri.Substring(0, queryDelimPos);
-					return new Uri(strippedUri + query);
-				}
-			}
-		}
-
-		public static Uri RemoveQuery(Uri original)
-		{
-			return CreateUriWithQuery(original, null);
-		}
-
-		public static CompositeData ParseComposite(Uri uri)
-		{
-			CompositeData rc = new CompositeData();
-			rc.Scheme = uri.Scheme;
-
-			// Start with original URI
-			//String ssp = uri.Authority + uri.PathAndQuery;
-			String ssp = uri.OriginalString;
-
-			ssp = StripPrefix(ssp, rc.Scheme + ":");
-			ssp = StripPrefix(ssp, "//");
-
-			int lastPoundPos = ssp.LastIndexOf("#");
-			int lastParendPos = ssp.LastIndexOf(")");
-
-			// Only include a Fragment that's outside any Composte sections.
-			if(lastPoundPos > lastParendPos)
-			{
-				rc.Fragment = ssp.Substring(lastPoundPos);
-				ssp = ssp.Substring(0, lastPoundPos);
-			}
-
-			// Ensure any embedded URIs don't have malformed authority's by changing
-			// them from '://(' which would cause the .NET Uri class to attempt to validate
-			// the authority as a hostname with, ':(' which is valid.
-			ssp = ssp.Replace("://(", ":(");
-
-			// Handle the composite components
-			ParseComposite(uri, rc, ssp);
-			return rc;
-		}
-
-		/// <summary>
-		/// </summary>
-		/// <param name="uri"></param>
-		/// <param name="rc"></param>
-		/// <param name="ssp"></param>
-		private static void ParseComposite(Uri uri, CompositeData rc, String ssp)
-		{
-			String componentString;
-			String parms;
-
-			if(!CheckParenthesis(ssp))
-			{
-				throw new NMSException(uri.ToString() + ": Not a matching number of '(' and ')' parenthesis");
-			}
-
-			int p;
-			int intialParen = ssp.IndexOf("(");
-
-			if(intialParen >= 0)
-			{
-				rc.Host = ssp.Substring(0, intialParen);
-				p = rc.Host.IndexOf("/");
-				if(p >= 0)
-				{
-					rc.Path = rc.Host.Substring(p);
-					rc.Host = rc.Host.Substring(0, p);
-				}
-
-				p = ssp.LastIndexOf(")");
-				int start = intialParen + 1;
-				int len = p - start;
-				componentString = ssp.Substring(start, len);
-				parms = ssp.Substring(p + 1).Trim();
-			}
-			else
-			{
-				componentString = ssp;
-				parms = "";
-			}
-
-			String[] components = SplitComponents(componentString);
-			rc.Components = new Uri[components.Length];
-			for(int i = 0; i < components.Length; i++)
-			{
-				rc.Components[i] = new Uri(components[i].Trim());
-			}
-
-			p = parms.IndexOf("?");
-			if(p >= 0)
-			{
-				if(p > 0)
-				{
-					rc.Path = StripPrefix(parms.Substring(0, p), "/");
-				}
-
-				rc.Parameters = ParseQuery(parms.Substring(p + 1));
-			}
-			else
-			{
-				if(parms.Length > 0)
-				{
-					rc.Path = StripPrefix(parms, "/");
-				}
-
-				rc.Parameters = EmptyMap;
-			}
-		}
-
-		private static StringDictionary EmptyMap
-		{
-			get { return new StringDictionary(); }
-		}
-
-		/// <summary>
-		/// </summary>
-		/// <param name="componentString"></param>
-		private static String[] SplitComponents(String componentString)
-		{
-			ArrayList l = new ArrayList();
-
-			int last = 0;
-			int depth = 0;
-			char[] chars = componentString.ToCharArray();
-			for(int i = 0; i < chars.Length; i++)
-			{
-				switch(chars[i])
-				{
-				case '(':
-					depth++;
-					break;
-
-				case ')':
-					depth--;
-					break;
-
-				case ',':
-					if(depth == 0)
-					{
-						String s = componentString.Substring(last, i - last);
-						l.Add(s);
-						last = i + 1;
-					}
-					break;
-
-				default:
-					break;
-				}
-			}
-
-			String ending = componentString.Substring(last);
-			if(ending.Length != 0)
-			{
-				l.Add(ending);
-			}
-
-			String[] rc = new String[l.Count];
-			l.CopyTo(rc);
-			return rc;
-		}
-
-		public static bool CheckParenthesis(String str)
-		{
-			bool result = true;
-
-			if(str != null)
-			{
-				int open = 0;
-				int closed = 0;
-
-				int i = 0;
-				while((i = str.IndexOf('(', i)) >= 0)
-				{
-					i++;
-					open++;
-				}
-
-				i = 0;
-				while((i = str.IndexOf(')', i)) >= 0)
-				{
-					i++;
-					closed++;
-				}
-
-				result = (open == closed);
-			}
-
-			return result;
-		}
-	}
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Globalization;
+using System.Reflection;
+using System.Text;
+#if !NETCF
+using System.Web;
+#endif
+
+namespace Apache.NMS.Util
+{
+	/// <summary>
+	/// Class to provide support for Uri query parameters which uses .Net reflection
+	/// to identify and set properties.
+	/// </summary>
+	public class URISupport
+	{
+		/// <summary>
+		/// Given a string that could be a Composite Uri that uses syntax not compatible
+		/// with the .NET Uri class such as an ActiveMQ failover Uri formatted as
+		/// "failover://(tcp://localhost:61616)", the initial '://' must be changed
+		/// to ':(' so that the Uri class doesn't attempt to parse the '(tcp:' as
+		/// the Uri's Authority as that is not a valid host name.
+		/// </summary>
+		/// <param name="uriString">
+		/// A string that could be a Composite Uri that uses syntax not compatible
+		/// with the .NET Uri class
+		/// </param>
+		public static Uri CreateCompatibleUri(string uriString)
+		{
+			string sanitized = uriString.Replace("://(", ":(");
+			return new Uri(sanitized);
+		}
+
+		/// <summary>
+		/// Parse a Uri query string of the form ?x=y&amp;z=0
+		/// into a map of name/value pairs.
+		/// </summary>
+		/// <param name="query">The query string to parse. This string should not contain
+		/// Uri escape characters.</param>
+		public static StringDictionary ParseQuery(String query)
+		{
+			StringDictionary map = new StringDictionary();
+
+			if(String.IsNullOrEmpty(query))
+			{
+				return EmptyMap;
+			}
+
+			// strip the initial "?"
+			if(query.StartsWith("?"))
+			{
+				query = query.Substring(1);
+			}
+
+			// split the query into parameters
+			string[] parameters = query.Split('&');
+			foreach(string pair in parameters)
+			{
+				if(pair.Length > 0)
+				{
+					string[] nameValue = pair.Split('=');
+
+					if(nameValue.Length != 2)
+					{
+						throw new NMSException(string.Format("Invalid Uri parameter: {0}", query));
+					}
+
+					map[UrlDecode(nameValue[0])] = UrlDecode(nameValue[1]);
+				}
+			}
+
+			return map;
+		}
+
+		public static StringDictionary ParseParameters(Uri uri)
+		{
+			return (uri.Query == null
+					? EmptyMap
+					: ParseQuery(StripPrefix(uri.Query, "?")));
+		}
+
+		/// <summary>
+		/// Sets the public properties of a target object using a string map.
+		/// This method uses .Net reflection to identify public properties of
+		/// the target object matching the keys from the passed map.
+		/// </summary>
+		/// <param name="target">The object whose properties will be set.</param>
+		/// <param name="map">Map of key/value pairs.</param>
+		public static void SetProperties(object target, StringDictionary map)
+		{
+			Type type = target.GetType();
+
+			foreach(string key in map.Keys)
+			{
+				PropertyInfo prop = type.GetProperty(key,
+														BindingFlags.FlattenHierarchy
+														| BindingFlags.Public
+														| BindingFlags.Instance
+														| BindingFlags.IgnoreCase);
+
+				if(null != prop)
+				{
+					prop.SetValue(target, Convert.ChangeType(map[key], prop.PropertyType, CultureInfo.InvariantCulture), null);
+				}
+				else
+				{
+					FieldInfo field = type.GetField(key,
+														BindingFlags.FlattenHierarchy
+														| BindingFlags.Public
+														| BindingFlags.Instance
+														| BindingFlags.IgnoreCase);
+					if(null != field)
+					{
+						field.SetValue(target, Convert.ChangeType(map[key], field.FieldType, CultureInfo.InvariantCulture));
+					}
+					else
+					{
+						throw new NMSException(string.Format("No such property or field: {0} on class: {1}", key, target.GetType().Name));
+					}
+				}
+			}
+		}
+
+		/// <summary>
+		/// Sets the public properties of a target object using a string map.
+		/// This method uses .Net reflection to identify public properties of
+		/// the target object matching the keys from the passed map.
+		/// </summary>
+		/// <param name="target">The object whose properties will be set.</param>
+		/// <param name="map">Map of key/value pairs.</param>
+		/// <param name="prefix">Key value prefix.  This is prepended to the property name
+		/// before searching for a matching key value.</param>
+		public static void SetProperties(object target, StringDictionary map, string prefix)
+		{
+			Type type = target.GetType();
+
+			List<String> matches = new List<String>();
+
+			foreach(string key in map.Keys)
+			{
+				if(key.StartsWith(prefix, StringComparison.InvariantCultureIgnoreCase))
+				{
+					string bareKey = key.Substring(prefix.Length);
+					PropertyInfo prop = type.GetProperty(bareKey,
+															BindingFlags.FlattenHierarchy
+															| BindingFlags.Public
+															| BindingFlags.Instance
+															| BindingFlags.IgnoreCase);
+
+					if(null != prop)
+					{
+						prop.SetValue(target, Convert.ChangeType(map[key], prop.PropertyType, CultureInfo.InvariantCulture), null);
+					}
+					else
+					{
+						FieldInfo field = type.GetField(bareKey,
+															BindingFlags.FlattenHierarchy
+															| BindingFlags.Public
+															| BindingFlags.Instance
+															| BindingFlags.IgnoreCase);
+						if(null != field)
+						{
+							field.SetValue(target, Convert.ChangeType(map[key], field.FieldType, CultureInfo.InvariantCulture));
+						}
+						else
+						{
+							throw new NMSException(string.Format("No such property or field: {0} on class: {1}", bareKey, target.GetType().Name));
+						}
+					}
+
+					// store for later removal.
+					matches.Add(key);
+				}
+			}
+
+			// Remove all the properties we set so they are used again later.
+			foreach(string match in matches)
+			{
+				map.Remove(match);
+			}
+		}
+
+		public static StringDictionary GetProperties(StringDictionary props, string prefix)
+		{
+			if(props == null)
+			{
+				throw new Exception("Properties Object was null");
+			}
+
+			StringDictionary result = new StringDictionary();
+
+			foreach(string key in props.Keys)
+			{
+				if(key.StartsWith(prefix, StringComparison.InvariantCultureIgnoreCase))
+				{
+					string bareKey = key.Substring(prefix.Length);
+					String value = props[key];
+					result[bareKey] = value;
+				}
+			}
+
+			return result;
+		}
+
+		public static StringDictionary ExtractProperties(StringDictionary props, string prefix)
+		{
+
+			if(props == null)
+			{
+				throw new Exception("Properties Object was null");
+			}
+
+			StringDictionary result = new StringDictionary();
+			List<String> matches = new List<String>();
+
+			foreach(string key in props.Keys)
+			{
+				if(key.StartsWith(prefix, StringComparison.InvariantCultureIgnoreCase))
+				{
+					String value = props[key];
+					result[key] = value;
+					matches.Add(key);
+				}
+			}
+
+			foreach(string match in matches)
+			{
+				props.Remove(match);
+			}
+
+			return result;
+		}
+
+		public static String UrlDecode(String s)
+		{
+#if !NETCF
+			return HttpUtility.UrlDecode(s);
+#else
+            return Uri.UnescapeDataString(s);
+#endif
+		}
+
+		public static String UrlEncode(String s)
+		{
+#if !NETCF
+			return HttpUtility.UrlEncode(s);
+#else
+            return Uri.EscapeUriString(s);
+#endif
+		}
+
+		public static String CreateQueryString(StringDictionary options)
+		{
+			if(options != null && options.Count > 0)
+			{
+				StringBuilder rc = new StringBuilder();
+				bool first = true;
+
+				foreach(String key in options.Keys)
+				{
+					string value = options[key];
+
+					if(first)
+					{
+						first = false;
+					}
+					else
+					{
+						rc.Append("&");
+					}
+
+					rc.Append(UrlEncode(key));
+					rc.Append("=");
+					rc.Append(UrlEncode(value));
+				}
+
+				return rc.ToString();
+			}
+			else
+			{
+				return "";
+			}
+		}
+
+		public static Uri CreateRemainingUri(Uri originalUri, StringDictionary parameters)
+		{
+			string s = CreateQueryString(parameters);
+
+			if(String.IsNullOrEmpty(s))
+			{
+				s = null;
+			}
+
+			return CreateUriWithQuery(originalUri, s);
+		}
+
+		public class CompositeData
+		{
+			private String host;
+			private String scheme;
+			private String path;
+			private Uri[] components;
+			private StringDictionary parameters;
+			private String fragment;
+
+			public Uri[] Components
+			{
+				get { return components; }
+				set { components = value; }
+			}
+
+			public String Fragment
+			{
+				get { return fragment; }
+				set { fragment = value; }
+			}
+
+			public StringDictionary Parameters
+			{
+				get { return parameters; }
+				set { parameters = value; }
+			}
+
+			public String Scheme
+			{
+				get { return scheme; }
+				set { scheme = value; }
+			}
+
+			public String Path
+			{
+				get { return path; }
+				set { path = value; }
+			}
+
+			public String Host
+			{
+				get { return host; }
+				set { host = value; }
+			}
+
+			public Uri toUri()
+			{
+				StringBuilder sb = new StringBuilder();
+				if(scheme != null)
+				{
+					sb.Append(scheme);
+					sb.Append(':');
+				}
+
+				if(!string.IsNullOrEmpty(host))
+				{
+					sb.Append(host);
+				}
+				else
+				{
+					sb.Append('(');
+					for(int i = 0; i < components.Length; i++)
+					{
+						if(i != 0)
+						{
+							sb.Append(',');
+						}
+						sb.Append(components[i].ToString());
+					}
+					sb.Append(')');
+				}
+
+				if(path != null)
+				{
+					sb.Append('/');
+					sb.Append(path);
+				}
+
+				if(parameters.Count != 0)
+				{
+					sb.Append("?");
+					sb.Append(CreateQueryString(parameters));
+				}
+
+				if(fragment != null)
+				{
+					sb.Append("#");
+					sb.Append(fragment);
+				}
+
+				return new Uri(sb.ToString());
+			}
+		}
+
+		public static String StripPrefix(String value, String prefix)
+		{
+			if(value.StartsWith(prefix, StringComparison.InvariantCultureIgnoreCase))
+			{
+				return value.Substring(prefix.Length);
+			}
+
+			return value;
+		}
+
+		public static Uri CreateUriWithQuery(Uri uri, string query)
+		{
+			if(!String.IsNullOrEmpty(query) && !query.StartsWith("?"))
+			{
+				query = "?" + query;
+			}
+
+			if(String.IsNullOrEmpty(uri.Query))
+			{
+				return new Uri(uri.OriginalString + query);
+			}
+			else
+			{
+				string originalUri = uri.OriginalString;
+
+				int queryDelimPos = originalUri.LastIndexOf('?');
+				int compositeDelimPos = originalUri.LastIndexOf(')');
+
+				if(queryDelimPos <= compositeDelimPos)
+				{
+					// No Query or the Query is part of an inner Composite.
+					return new Uri(originalUri + query);
+				}
+				else
+				{
+					// Outer Uri has a Query or not a Composite Uri with a Query
+					string strippedUri = originalUri.Substring(0, queryDelimPos);
+					return new Uri(strippedUri + query);
+				}
+			}
+		}
+
+		public static Uri RemoveQuery(Uri original)
+		{
+			return CreateUriWithQuery(original, null);
+		}
+
+		public static CompositeData ParseComposite(Uri uri)
+		{
+			CompositeData rc = new CompositeData();
+			rc.Scheme = uri.Scheme;
+
+			// Start with original URI
+			//String ssp = uri.Authority + uri.PathAndQuery;
+			String ssp = uri.OriginalString;
+
+			ssp = StripPrefix(ssp, rc.Scheme + ":");
+			ssp = StripPrefix(ssp, "//");
+
+			int lastPoundPos = ssp.LastIndexOf("#");
+			int lastParendPos = ssp.LastIndexOf(")");
+
+			// Only include a Fragment that's outside any Composte sections.
+			if(lastPoundPos > lastParendPos)
+			{
+				rc.Fragment = ssp.Substring(lastPoundPos);
+				ssp = ssp.Substring(0, lastPoundPos);
+			}
+
+			// Ensure any embedded URIs don't have malformed authority's by changing
+			// them from '://(' which would cause the .NET Uri class to attempt to validate
+			// the authority as a hostname with, ':(' which is valid.
+			ssp = ssp.Replace("://(", ":(");
+
+			// Handle the composite components
+			ParseComposite(uri, rc, ssp);
+			return rc;
+		}
+
+		/// <summary>
+		/// </summary>
+		/// <param name="uri"></param>
+		/// <param name="rc"></param>
+		/// <param name="ssp"></param>
+		private static void ParseComposite(Uri uri, CompositeData rc, String ssp)
+		{
+			String componentString;
+			String parms;
+
+			if(!CheckParenthesis(ssp))
+			{
+				throw new NMSException(uri.ToString() + ": Not a matching number of '(' and ')' parenthesis");
+			}
+
+			int p;
+			int intialParen = ssp.IndexOf("(");
+
+			if(intialParen >= 0)
+			{
+				rc.Host = ssp.Substring(0, intialParen);
+				p = rc.Host.IndexOf("/");
+				if(p >= 0)
+				{
+					rc.Path = rc.Host.Substring(p);
+					rc.Host = rc.Host.Substring(0, p);
+				}
+
+				p = ssp.LastIndexOf(")");
+				int start = intialParen + 1;
+				int len = p - start;
+				componentString = ssp.Substring(start, len);
+				parms = ssp.Substring(p + 1).Trim();
+			}
+			else
+			{
+				componentString = ssp;
+				parms = "";
+			}
+
+			String[] components = SplitComponents(componentString);
+			rc.Components = new Uri[components.Length];
+			for(int i = 0; i < components.Length; i++)
+			{
+				rc.Components[i] = new Uri(components[i].Trim());
+			}
+
+			p = parms.IndexOf("?");
+			if(p >= 0)
+			{
+				if(p > 0)
+				{
+					rc.Path = StripPrefix(parms.Substring(0, p), "/");
+				}
+
+				rc.Parameters = ParseQuery(parms.Substring(p + 1));
+			}
+			else
+			{
+				if(parms.Length > 0)
+				{
+					rc.Path = StripPrefix(parms, "/");
+				}
+
+				rc.Parameters = EmptyMap;
+			}
+		}
+
+		private static StringDictionary EmptyMap
+		{
+			get { return new StringDictionary(); }
+		}
+
+		/// <summary>
+		/// </summary>
+		/// <param name="componentString"></param>
+		private static String[] SplitComponents(String componentString)
+		{
+			ArrayList l = new ArrayList();
+
+			int last = 0;
+			int depth = 0;
+			char[] chars = componentString.ToCharArray();
+			for(int i = 0; i < chars.Length; i++)
+			{
+				switch(chars[i])
+				{
+				case '(':
+					depth++;
+					break;
+
+				case ')':
+					depth--;
+					break;
+
+				case ',':
+					if(depth == 0)
+					{
+						String s = componentString.Substring(last, i - last);
+						l.Add(s);
+						last = i + 1;
+					}
+					break;
+
+				default:
+					break;
+				}
+			}
+
+			String ending = componentString.Substring(last);
+			if(ending.Length != 0)
+			{
+				l.Add(ending);
+			}
+
+			String[] rc = new String[l.Count];
+			l.CopyTo(rc);
+			return rc;
+		}
+
+		public static bool CheckParenthesis(String str)
+		{
+			bool result = true;
+
+			if(str != null)
+			{
+				int open = 0;
+				int closed = 0;
+
+				int i = 0;
+				while((i = str.IndexOf('(', i)) >= 0)
+				{
+					i++;
+					open++;
+				}
+
+				i = 0;
+				while((i = str.IndexOf(')', i)) >= 0)
+				{
+					i++;
+					closed++;
+				}
+
+				result = (open == closed);
+			}
+
+			return result;
+		}
+	}
+}
diff --git a/src/test/csharp/URISupportTest.cs b/src/test/csharp/URISupportTest.cs
index 825ed9d..f60355b 100644
--- a/src/test/csharp/URISupportTest.cs
+++ b/src/test/csharp/URISupportTest.cs
@@ -21,6 +21,9 @@
 using Apache.NMS.Util;
 
 using NUnit.Framework;
+#if !NETCF
+using System.Web;
+#endif
 
 namespace Apache.NMS.Test
 {
@@ -266,6 +269,28 @@
 	        Assert.IsFalse(dest.Query.Equals(source.Query), "same uri, ssp");
 	    }
 
+
+#if !NETCF
+		[Test]
+        public void TestParseQueryEncoding() {
+
+			String paramName = "name";
+            String paramValue = "CN=Test, OU=bla, ..&%/§()%3q743847)/(&%/.. hjUIFHUFH";
+
+            String uriString = "http://someserver.com:1234/?";
+
+            //encoding the param with url encode
+            uriString += paramName + "=" + HttpUtility.UrlEncode(paramValue);
+
+            Uri uri = new Uri(uriString);
+
+            StringDictionary dictionary = URISupport.ParseQuery(uri.Query);
+
+            String value = dictionary[paramName];
+
+            NUnit.Framework.Assert.AreEqual(paramValue, value);
+        }
+#endif
 	}
 }
 
