Tag the initial code used for a 1.3.0 vote
diff --git a/nant.build b/nant.build
index b70d6f1..0079624 100644
--- a/nant.build
+++ b/nant.build
@@ -22,7 +22,7 @@
     <property name="basedir" value="${project::get-base-directory()}" />
     <property name="project.name" value="Apache.NMS.ActiveMQ" />
     <property name="project.group" value="org.apache.activemq" />
-    <property name="project.version" value="1.3.x" unless="${property::exists('project.version')}" />
+    <property name="project.version" value="1.3.0" unless="${property::exists('project.version')}" />
     <property name="project.release.type" value="GA" unless="${property::exists('project.release.type')}" />
     <property name="project.short_description" value="Apache NMS for ActiveMQ Class Library" />
     <property name="project.description" value="Apache NMS for ActiveMQ Class Library (.Net Messaging Library Implementation): An implementation of the NMS API for ActiveMQ" />
diff --git a/src/main/csharp/Transport/Tcp/TcpTransportFactory.cs b/src/main/csharp/Transport/Tcp/TcpTransportFactory.cs
index 121b725..6ddc56a 100644
--- a/src/main/csharp/Transport/Tcp/TcpTransportFactory.cs
+++ b/src/main/csharp/Transport/Tcp/TcpTransportFactory.cs
@@ -116,9 +116,28 @@
             // Set transport. properties on this (the factory)
             URISupport.SetProperties(this, map, "transport.");
 
-            Tracer.Debug("Opening socket to: " + location.Host + " on port: " + location.Port);
-            Socket socket = Connect(location.Host, location.Port);
-
+			// See if there is a local address and port specified
+			string localAddress = null;
+			int localPort = -1;
+			
+			if(!String.IsNullOrEmpty(location.AbsolutePath) && !location.AbsolutePath.Equals("/"))
+			{
+				int index = location.AbsolutePath.IndexOf(':');
+				try
+				{
+					localPort = Int16.Parse(location.AbsolutePath.Substring(index + 1));					
+					localAddress = location.AbsolutePath.Substring(1, index - 1);
+					Tracer.DebugFormat("Binding Socket to {0} on port: {1}", localAddress, localPort);
+				}
+				catch
+				{
+            		Tracer.Warn("Invalid Port value on URI for local bind option, ignoring.");
+				}
+			}
+			
+            Tracer.Debug("Opening socket to: " + location.Host + " on port: " + location.Port);            
+			Socket socket = DoConnect(location.Host, location.Port, localAddress, localPort );
+			
 #if !NETCF
             socket.ReceiveBufferSize = ReceiveBufferSize;
             socket.SendBufferSize = SendBufferSize;
@@ -220,7 +239,7 @@
             return ipEntry;
         }
 
-        private Socket ConnectSocket(IPAddress address, int port)
+        private Socket TryConnectSocket(IPAddress address, int port, string localAddress, int localPort)
         {
             if(null != address)
             {
@@ -230,6 +249,11 @@
 
                     if(null != socket)
                     {
+						if(!String.IsNullOrEmpty(localAddress))
+						{
+							DoBind(socket, localAddress, localPort);
+						}
+						
                         socket.Connect(new IPEndPoint(address, port));
                         if(socket.Connected)
                         {
@@ -292,7 +316,7 @@
             return null;
         }
 
-        protected Socket Connect(string host, int port)
+        protected Socket DoConnect(string host, int port, string localAddress, int localPort)
         {
             Socket socket = null;
             IPAddress ipaddress;
@@ -301,7 +325,7 @@
             {
                 if(TryParseIPAddress(host, out ipaddress))
                 {
-                    socket = ConnectSocket(ipaddress, port);
+                    socket = TryConnectSocket(ipaddress, port, localAddress, localPort);
                 }
                 else
                 {
@@ -313,12 +337,12 @@
                     {
                         // Prefer IPv6 first.
                         ipaddress = GetIPAddress(hostEntry, AddressFamily.InterNetworkV6);
-                        socket = ConnectSocket(ipaddress, port);
+                        socket = TryConnectSocket(ipaddress, port, localAddress, localPort);
                         if(null == socket)
                         {
                             // Try IPv4 next.
                             ipaddress = GetIPAddress(hostEntry, AddressFamily.InterNetwork);
-                            socket = ConnectSocket(ipaddress, port);
+                            socket = TryConnectSocket(ipaddress, port, localAddress, localPort);
                             if(null == socket)
                             {
                                 // Try whatever else there is.
@@ -331,7 +355,7 @@
                                         continue;
                                     }
 
-                                    socket = ConnectSocket(address, port);
+                            		socket = TryConnectSocket(ipaddress, port, localAddress, localPort);
                                     if(null != socket)
                                     {
                                         ipaddress = address;
@@ -356,5 +380,86 @@
             Tracer.DebugFormat("Connected to {0}:{1} using {2} protocol.", host, port, ipaddress.AddressFamily.ToString());
             return socket;
         }
+		
+        protected void DoBind(Socket socket, string host, int port)
+        {
+            IPAddress ipaddress;
+
+            try
+            {
+                if(TryParseIPAddress(host, out ipaddress))
+                {
+                    TryBindSocket(socket, ipaddress, port);
+                }
+                else
+                {
+                    // Looping through the AddressList allows different type of connections to be tried
+                    // (IPv6, IPv4 and whatever else may be available).
+                    IPHostEntry hostEntry = GetIPHostEntry(host);
+
+                    if(null != hostEntry)
+                    {
+                        // Prefer IPv6 first.
+                        ipaddress = GetIPAddress(hostEntry, AddressFamily.InterNetworkV6);
+                        if(!TryBindSocket(socket, ipaddress, port))
+                        {
+                            // Try IPv4 next.
+                            ipaddress = GetIPAddress(hostEntry, AddressFamily.InterNetwork);
+	                        if(!TryBindSocket(socket, ipaddress, port))
+                            {
+                                // Try whatever else there is.
+                                foreach(IPAddress address in hostEntry.AddressList)
+                                {
+                                    if(AddressFamily.InterNetworkV6 == address.AddressFamily
+                                        || AddressFamily.InterNetwork == address.AddressFamily)
+                                    {
+                                        // Already tried these protocols.
+                                        continue;
+                                    }
+
+                        			if(TryBindSocket(socket, ipaddress, port))
+                                    {
+                                        ipaddress = address;
+                                        break;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+
+                if(!socket.IsBound)
+                {
+                    throw new SocketException();
+                }
+            }
+            catch(Exception ex)
+            {
+                throw new NMSConnectionException(String.Format("Error binding to {0}:{1}.", host, port), ex);
+            }
+
+            Tracer.DebugFormat("Bound to {0}:{1} using.", host, port);
+        }		
+		
+        private bool TryBindSocket(Socket socket, IPAddress address, int port)
+        {
+            if(null != socket && null != address)
+            {
+                try
+                {
+                    socket.Bind(new IPEndPoint(address, port));
+                    if(socket.IsBound)
+                    {
+                        return true;
+                    }
+                }
+                catch
+                {
+                }
+            }
+
+            return false;
+        }
+		
     }
 }
diff --git a/src/test/csharp/NMSConnectionFactoryTest.cs b/src/test/csharp/NMSConnectionFactoryTest.cs
index 45053c2..4c8c731 100644
--- a/src/test/csharp/NMSConnectionFactoryTest.cs
+++ b/src/test/csharp/NMSConnectionFactoryTest.cs
@@ -36,6 +36,7 @@
 		[RowTest]

 		[Row("tcp://${activemqhost}:61616")]

 		[Row("activemq:tcp://${activemqhost}:61616")]

+		[Row("activemq:tcp://${activemqhost}:61616/0.0.0.0:0")]

 		[Row("activemq:tcp://${activemqhost}:61616?connection.asyncclose=false")]

 		[Row("activemq:failover:tcp://${activemqhost}:61616")]

 		[Row("activemq:failover:(tcp://${activemqhost}:61616)")]

@@ -48,6 +49,8 @@
 		[Row("activemq:failover:(discovery:(multicast://default))")]

 #endif

 	

+		[Row("activemq:tcp://${activemqhost}:61616/InvalidHost:0", ExpectedException = typeof(NMSConnectionException))]

+		[Row("activemq:tcp://${activemqhost}:61616/0.0.0.0:-1", ExpectedException = typeof(NMSConnectionException))]

 		[Row("tcp://InvalidHost:61616", ExpectedException = typeof(NMSConnectionException))]

 		[Row("activemq:tcp://InvalidHost:61616", ExpectedException = typeof(NMSConnectionException))]

 		[Row("activemq:tcp://InvalidHost:61616?connection.asyncclose=false", ExpectedException = typeof(NMSConnectionException))]