Index: src/main/org/jboss/resource/connectionmanager/ManagedConnectionFactoryDeployment.java
===================================================================
--- src/main/org/jboss/resource/connectionmanager/ManagedConnectionFactoryDeployment.java	(revision 110403)
+++ src/main/org/jboss/resource/connectionmanager/ManagedConnectionFactoryDeployment.java	(working copy)
@@ -25,6 +25,7 @@
 import java.beans.PropertyEditorManager;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.io.File;
 import java.security.AccessController;
 import java.security.Principal;
 import java.security.PrivilegedAction;
@@ -378,6 +379,7 @@
 
       ResourceAdapter resourceAdapter = null;
       ConnectionDefinitionMetaData cdmd = cmd.getConnectionDefinition(dmd.getConnectionDefinition());
+      rarName = dmd.getRarName();
       
       try
       {
@@ -481,6 +483,12 @@
             if (log.isDebugEnabled())
                log.debug("Registered for XA Resource Recovery: " + xdsdm.getJndiName());
 
+            // Variable substitution
+            recoverUserName = getSubstitutionValue(recoverUserName);
+            recoverPassword = getSubstitutionValue(recoverPassword);
+            recoverSecurityDomain = getSubstitutionValue(recoverSecurityDomain);
+            securityDomain = getSubstitutionValue(securityDomain);
+
             if (log.isDebugEnabled())
             {
                if (recoverUserName != null)
@@ -550,17 +558,33 @@
                ManagedConnection mc = open(subject);
                XAResource xaResource = null;
 
+               Object connection = null;
                try
                {
                   xaResource = mc.getXAResource();
+                  connection = openConnection(mc, subject);
                }
                catch (ResourceException reconnect)
                {
+                  closeConnection(connection);
+                  connection = null;
                   close(mc);
                   mc = open(subject);
                   xaResource = mc.getXAResource();
                }
+               finally
+               {
+                  boolean forceDestroy = closeConnection(connection);
+                  connection = null;
 
+                  if (forceDestroy)
+                  {
+                     close(mc);
+                     mc = open(subject);
+                     xaResource = mc.getXAResource();
+                  }
+               }
+
                try
                {
                   ObjectName on = new ObjectName(connectionManager);
@@ -607,7 +631,8 @@
                }
                catch (Throwable t)
                {
-                  // Ignore
+                  if (log.isDebugEnabled())
+                     log.debug("Unable to verify wrap-xa settings for " + dmd.getJndiName(), t);
                }
 
                if (log.isDebugEnabled())
@@ -623,8 +648,7 @@
          }
          catch (ResourceException re)
          {
-            if (log.isDebugEnabled())
-               log.debug("Error during recovery", re);
+            log.warn("Error during recovery", re);
          }
       }
       else
@@ -715,7 +739,7 @@
                }
                catch (Throwable t)
                {
-                  log.debug("Exception during getSubject()" + t.getMessage(), t);
+                  log.warn("Exception during getSubject()" + t.getMessage(), t);
                }
 
                return null;
@@ -754,8 +778,7 @@
          }
          catch (ResourceException ire)
          {
-            if (log.isDebugEnabled())
-               log.debug("Error during recovery cleanup", ire);
+            log.warn("Error during recovery cleanup", ire);
          }
       }
 
@@ -767,13 +790,70 @@
          }
          catch (ResourceException ire)
          {
-            if (log.isDebugEnabled())
-               log.debug("Error during recovery destroy", ire);
+            log.warn("Error during recovery destroy", ire);
          }
       }
 
       mc = null;
    }
+
+   /**
+    * Open a connection
+    * @param mc The managed connection
+    * @param s The subject
+    * @return The connection handle
+    * @exception ResourceException Thrown in case of an error
+    */
+   private Object openConnection(ManagedConnection mc, Subject s) throws ResourceException
+   {
+      return mc.getConnection(s, null);
+   }
+
+   /**
+    * Close a connection
+    * @param c The connection
+    * @return Should the managed connection be forced closed
+    */
+   private boolean closeConnection(Object c)
+   {
+      if (c != null)
+      {
+         if (c instanceof javax.resource.cci.Connection)
+         {
+            try
+            {
+               javax.resource.cci.Connection cci = (javax.resource.cci.Connection)c;
+               cci.close();
+            }
+            catch (ResourceException ire)
+            {
+               log.warn("Error during recovery connection close", ire);
+               return true;
+            }
+         }
+         else
+         {
+            try
+            {
+               Method method = c.getClass().getMethod("close", new Class[0]);
+               method.setAccessible(true);
+               method.invoke(c, new Object[0]);
+            }
+            catch (NoSuchMethodException nsme)
+            {
+               log.warn("No close() method defined on connection interface. Destroying managed connection to clean-up", nsme);
+               return true;
+            }
+            catch (Throwable t)
+            {
+               log.warn("Error during recovery connection close", t);
+               return true;
+            }
+         }
+      }
+
+      return false;
+   }
    
    public void setManagedConnectionFactoryAttribute(String name, Class clazz, Object value)
    {
@@ -1211,4 +1291,113 @@
          description = "RAR Deployment ";
       return description;
    }
+
+   /**
+    * System property substitution
+    * @param input The input string
+    * @return The output
+    */
+   private String getSubstitutionValue(String input)
+   {
+      if (input == null || input.trim().equals(""))
+         return input;
+
+      while ((input.indexOf("${")) != -1)
+      {
+         int from = input.indexOf("${");
+         int to = input.indexOf("}");
+         int dv = input.indexOf(":", from + 2);
+
+         if (dv != -1)
+         {
+            if (dv > to)
+               dv = -1;
+         }
+
+         String systemProperty = "";
+         String defaultValue = "";
+         String s = input.substring(from + 2, to);
+         if (dv == -1)
+         {
+            if ("/".equals(s))
+            {
+               systemProperty = File.separator;
+            }
+            else if (":".equals(s))
+            {
+               systemProperty = File.pathSeparator;
+            }
+            else
+            {
+               systemProperty = SecurityActions.getSystemProperty(s);
+            }
+         }
+         else
+         {
+            s = input.substring(from + 2, dv);
+            systemProperty = SecurityActions.getSystemProperty(s);
+            defaultValue = input.substring(dv + 1, to);
+         }
+         String prefix = "";
+         String postfix = "";
+
+         if (from != 0)
+         {
+            prefix = input.substring(0, from);
+         }
+
+         if (to + 1 < input.length() - 1)
+         {
+            postfix = input.substring(to + 1);
+         }
+
+         if (systemProperty != null && !systemProperty.trim().equals(""))
+         {
+            input = prefix + systemProperty + postfix;
+         }
+         else if (defaultValue != null && !defaultValue.trim().equals(""))
+         {
+            input = prefix + defaultValue + postfix;
+         }
+         else
+         {
+            input = prefix + postfix;
+            log.debugf("System property %s not set", s);
+         }
+      }
+      return input;
+   }
+
+   private static class SecurityActions
+   {
+      /**
+       * Constructor
+       */
+      private SecurityActions()
+      {
+      }
+
+      /**
+       * Get a system property
+       * @param name The property name
+       * @return The property value
+       */
+      static String getSystemProperty(final String name)
+      {
+         if (System.getSecurityManager() == null)
+         {
+            return System.getProperty(name);
+         }
+         else
+         {
+            return (String) AccessController.doPrivileged(new PrivilegedAction<Object>()
+            {
+               public Object run()
+               {
+                  return System.getProperty(name);
+               }
+            });
+         }
+      }
+   }
 }
