entry = iterator.next();
+            sb.append(entry.getKey()).append("=").append(entry.getValue());
+
+            if (iterator.hasNext())
+               sb.append(":");
+         }
+      }
+
+      sb.append("-");
+      if (bootstrapContextName != null && !bootstrapContextName.trim().equals(""))
+      {
+         sb.append(bootstrapContextName);
+      }
+      else
+      {
+         sb.append(defaultBootstrapContext.getName());
+      }
+
+      return sb.toString();
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/bootstrapcontext/package.html
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/bootstrapcontext/package.html	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/bootstrapcontext/package.html	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,6 @@
+
+This package contains implementations of the BootstrapContext interface.
+
+IronJacamar extends javax.resource.spi.BootstrapContext with a org.jboss.jca.core.api.CloneableBootstrapContext
+interface in order to allow different implementations to be used for the resource adapter deployments.
+
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/bv/BeanValidation.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/bv/BeanValidation.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/bv/BeanValidation.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,138 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2009, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.bv;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.validation.Configuration;
+import javax.validation.Validation;
+import javax.validation.Validator;
+import javax.validation.ValidatorFactory;
+
+/**
+ * Bean validation implementation backed by Hibernate Validator
+ *
+ * @author Jesper Pedersen 
+ * @version $Revision: $
+ */
+public class BeanValidation
+{
+   /** Validator factory */
+   private static final String VALIDATOR_FACTORY = "java:/ValidatorFactory";
+
+   /** Validator */
+   private static final String VALIDATOR = "java:/Validator";
+
+   /** The validator factory */
+   private ValidatorFactory validatorFactory;
+
+   /** The validator */
+   private Validator validator;
+
+   /**
+    * Constructor
+    */
+   public BeanValidation()
+   {
+      Configuration configuration = Validation.byDefaultProvider().configure();
+      Configuration> conf = configuration.traversableResolver(new JCATraversableResolver());
+
+      validatorFactory = conf.buildValidatorFactory();
+      validator = validatorFactory.getValidator();
+   }
+
+   /**
+    * Get the validator factory
+    * @return The factory
+    */
+   public ValidatorFactory getValidatorFactory()
+   {
+      return validatorFactory;
+   }
+
+   /**
+    * Get the validator
+    * @return The validator
+    */
+   public Validator getValidator()
+   {
+      return validator;
+   }
+
+   /**
+    * Start
+    * @exception Throwable If an error occurs
+    */
+   public void start() throws Throwable
+   {
+      Context context = null;
+      try
+      {
+         context = new InitialContext();
+
+         context.rebind(VALIDATOR_FACTORY, new SerializableValidatorFactory(validatorFactory));
+         context.rebind(VALIDATOR, new SerializableValidator(validator));
+      }
+      finally
+      {
+         try
+         {
+            if (context != null)
+               context.close();
+         }
+         catch (NamingException ne)
+         {
+            // Ignore
+         }
+      }
+   }
+
+   /**
+    * Stop
+    * @exception Throwable If an error occurs
+    */
+   public void stop() throws Throwable
+   {
+      Context context = null;
+      try
+      {
+         context = new InitialContext();
+
+         context.unbind(VALIDATOR);
+         context.unbind(VALIDATOR_FACTORY);
+      }
+      finally
+      {
+         try
+         {
+            if (context != null)
+               context.close();
+         }
+         catch (NamingException ne)
+         {
+            // Ignore
+         }
+      }
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/bv/BeanValidationUtil.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/bv/BeanValidationUtil.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/bv/BeanValidationUtil.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,67 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2009, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.bv;
+
+import javax.validation.Configuration;
+import javax.validation.Validation;
+import javax.validation.Validator;
+import javax.validation.ValidatorFactory;
+
+/**
+ * Bean validation utility
+ *
+ * @author Jesper Pedersen 
+ * @version $Revision: $
+ */
+public class BeanValidationUtil
+{
+   /**
+    * Constructor
+    */
+   private BeanValidationUtil()
+   {
+   }
+
+   /**
+    * Create a validator factory
+    * @return The factory
+    */
+   public static ValidatorFactory createValidatorFactory()
+   {
+      Configuration configuration = Validation.byDefaultProvider().configure();
+      Configuration> conf = configuration.traversableResolver(new JCATraversableResolver());
+
+      return conf.buildValidatorFactory();
+   }
+
+   /**
+    * Create a validator
+    * @return The validator
+    */
+   public static Validator createValidator()
+   {
+      ValidatorFactory vf = createValidatorFactory();
+
+      return vf.getValidator();
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/bv/JCATraversableResolver.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/bv/JCATraversableResolver.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/bv/JCATraversableResolver.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,91 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2009, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.bv;
+
+import java.lang.annotation.ElementType;
+
+import javax.validation.Path;
+import javax.validation.TraversableResolver;
+
+/**
+ * JCATraversableResolver
+ * @author Jeff Zhang 
+ * @version $Revision: $
+ */
+public class JCATraversableResolver implements TraversableResolver
+{
+   /**
+    * Determine if Bean Validation is allowed to reach the property state
+    * 
+    * @param traversableObject
+    *           object hosting traversableProperty or null if
+    *           validateValue is called
+    * @param traversableProperty
+    *           the traversable property.
+    * @param rootBeanType
+    *           type of the root object passed to the Validator.
+    * @param pathToTraversableObject
+    *           path from the root object to traversableObject
+    *           (using the path specification defined by Bean Validator).
+    * @param elementType
+    *           either FIELD or METHOD.
+    * 
+    * @return true if Bean Validation is allowed to reach the
+    *         property state, false otherwise.
+    */
+   public boolean isReachable(Object traversableObject, Path.Node traversableProperty,
+         Class> rootBeanType, Path pathToTraversableObject,
+         ElementType elementType)
+   {
+      return true;
+   }
+
+   /**
+    * Determine if Bean Validation is allowed to cascade validation on the bean
+    * instance returned by the property value marked as @Valid.
+    * Note that this method is called only if isReachable returns true for the
+    * same set of arguments and if the property is marked as @Valid
+    * 
+    * @param traversableObject
+    *           object hosting traversableProperty or null if
+    *           validateValue is called
+    * @param traversableProperty
+    *           the traversable property.
+    * @param rootBeanType
+    *           type of the root object passed to the Validator.
+    * @param pathToTraversableObject
+    *           path from the root object to traversableObject
+    *           (using the path specification defined by Bean Validator).
+    * @param elementType
+    *           either FIELD or METHOD.
+    * 
+    * @return true if Bean Validation is allowed to cascade
+    *         validation, false otherwise.
+    */
+   public boolean isCascadable(Object traversableObject,
+         Path.Node traversableProperty, Class> rootBeanType,
+         Path pathToTraversableObject, ElementType elementType)
+   {
+      return true;
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/bv/SerializableValidator.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/bv/SerializableValidator.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/bv/SerializableValidator.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,137 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2009, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.bv;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.Set;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.Validator;
+import javax.validation.executable.ExecutableValidator;
+import javax.validation.metadata.BeanDescriptor;
+
+/**
+ * Serializable validator
+ *
+ * @author Jesper Pedersen 
+ * @version $Revision: $
+ */
+public class SerializableValidator implements Validator, Serializable
+{
+   /** Serial version uid */
+   private static final long serialVersionUID = 2L;
+
+   /** The validator */
+   private transient Validator validator;
+
+   /**
+    * Constructor
+    */
+   public SerializableValidator()
+   {
+      this(BeanValidationUtil.createValidator());
+   }
+
+   /**
+    * Constructor
+    * @param v The validator
+    */
+   public SerializableValidator(Validator v)
+   {
+      this.validator = v;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public BeanDescriptor getConstraintsForClass(Class> clazz)
+   {
+      return validator.getConstraintsForClass(clazz);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public  Set> validate(T object, Class>... groups)
+   {
+      return validator.validate(object, groups);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public  Set> validateProperty(T object, String propertyName, Class>... groups)
+   {
+      return validator.validateProperty(object, propertyName, groups);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public  Set> validateValue(Class beanType, 
+                                                        String propertyName, 
+                                                        Object value, 
+                                                        Class>... groups)
+   {
+      return validator.validateValue(beanType, propertyName, value, groups);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public  T unwrap(Class type)
+   {
+      return validator.unwrap(type);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public ExecutableValidator forExecutables()
+   {
+      return validator.forExecutables();
+   }
+
+   /**
+    * Write the object - Nothing is written as the validator factory is transient
+    * @param out The output stream
+    * @exception IOException Thrown if an error occurs
+    */
+   private void writeObject(ObjectOutputStream out) throws IOException
+   {
+   }
+
+   /**
+    * Read the object - Nothing is read as the validator factory is transient.
+    * A new instance is created
+    * @param out The output stream
+    * @exception IOException Thrown if an error occurs
+    */
+   private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
+   {
+      validator = BeanValidationUtil.createValidator();
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/bv/SerializableValidatorFactory.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/bv/SerializableValidatorFactory.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/bv/SerializableValidatorFactory.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,152 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2009, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.bv;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+
+import javax.validation.ConstraintValidatorFactory;
+import javax.validation.MessageInterpolator;
+import javax.validation.ParameterNameProvider;
+import javax.validation.TraversableResolver;
+import javax.validation.Validator;
+import javax.validation.ValidatorContext;
+import javax.validation.ValidatorFactory;
+
+/**
+ * Serializable validator factory
+ *
+ * @author Jesper Pedersen 
+ * @version $Revision: $
+ */
+public class SerializableValidatorFactory implements ValidatorFactory, Serializable
+{
+   /** Serial version uid */
+   private static final long serialVersionUID = 2L;
+
+   /** The validator factory */
+   private transient ValidatorFactory validatorFactory;
+
+   /**
+    * Constructor
+    */
+   public SerializableValidatorFactory()
+   {
+      this(BeanValidationUtil.createValidatorFactory());
+   }
+
+   /**
+    * Constructor
+    * @param vf The validator factory
+    */
+   public SerializableValidatorFactory(ValidatorFactory vf)
+   {
+      this.validatorFactory = vf;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public MessageInterpolator getMessageInterpolator()
+   {
+      return validatorFactory.getMessageInterpolator();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public Validator getValidator()
+   {
+      return validatorFactory.getValidator();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public ValidatorContext usingContext()
+   {
+      return validatorFactory.usingContext();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public  T unwrap(Class type)
+   {
+      return validatorFactory.unwrap(type);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public ConstraintValidatorFactory getConstraintValidatorFactory()
+   {
+      return validatorFactory.getConstraintValidatorFactory();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public TraversableResolver getTraversableResolver()
+   {
+      return validatorFactory.getTraversableResolver();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public ParameterNameProvider getParameterNameProvider()
+   {
+      return validatorFactory.getParameterNameProvider();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void close()
+   {
+      validatorFactory.close();
+   }
+
+   /**
+    * Write the object - Nothing is written as the validator factory is transient
+    * @param out The output stream
+    * @exception IOException Thrown if an error occurs
+    */
+   private void writeObject(ObjectOutputStream out) throws IOException
+   {
+   }
+
+   /**
+    * Read the object - Nothing is read as the validator factory is transient.
+    * A new instance is created
+    * @param out The output stream
+    * @exception IOException Thrown if an error occurs
+    */
+   private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
+   {
+      validatorFactory = BeanValidationUtil.createValidatorFactory();
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/bv/package.html
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/bv/package.html	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/bv/package.html	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,3 @@
+
+This package contains the bean validation service.
+
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/AbstractConnectionManager.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/AbstractConnectionManager.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/AbstractConnectionManager.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,1077 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2008-2009, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager;
+
+import org.jboss.jca.common.api.metadata.common.FlushStrategy;
+import org.jboss.jca.core.CoreBundle;
+import org.jboss.jca.core.CoreLogger;
+import org.jboss.jca.core.api.connectionmanager.ccm.CachedConnectionManager;
+import org.jboss.jca.core.api.management.ManagedEnlistmentTrace;
+import org.jboss.jca.core.connectionmanager.listener.ConnectionListener;
+import org.jboss.jca.core.connectionmanager.listener.ConnectionState;
+import org.jboss.jca.core.connectionmanager.pool.api.Pool;
+import org.jboss.jca.core.spi.graceful.GracefulCallback;
+import org.jboss.jca.core.spi.security.SubjectFactory;
+import org.jboss.jca.core.spi.transaction.TransactionIntegration;
+
+import java.util.Collection;
+import java.util.Set;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.ConnectionRequestInfo;
+import javax.resource.spi.ManagedConnection;
+import javax.resource.spi.ManagedConnectionFactory;
+import javax.resource.spi.RetryableException;
+import javax.resource.spi.security.PasswordCredential;
+import javax.security.auth.Subject;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+
+import org.jboss.logging.Messages;
+
+/**
+ * AbstractConnectionManager.
+ *
+ * @author Gurkan Erdogdu 
+ * @author Jesper Pedersen 
+ */
+public abstract class AbstractConnectionManager implements ConnectionManager
+{
+   /** Empty graceful shutdown call back */
+   private static final GracefulCallback EMPTY_CALL_BACK = new GracefulCallback()
+   {
+      @Override public void cancel()
+      {
+         // do nothing
+      }
+
+      @Override public void done()
+      {
+         // do nothing
+      }
+   };
+
+
+   /** Log instance */
+   private final CoreLogger log;
+
+   /** The bundle */
+   private static CoreBundle bundle = Messages.getBundle(CoreBundle.class);
+   
+   /** The pool */
+   private Pool pool;
+
+   /** Security domain */
+   private String securityDomain;
+
+   /** SubjectFactory */
+   private SubjectFactory subjectFactory;
+
+   /** The flush strategy */
+   private FlushStrategy flushStrategy;
+
+   /** Number of retry to allocate connection */
+   private int allocationRetry;
+
+   /** Interval between retries */
+   private long allocationRetryWaitMillis;
+
+   /** Startup/ShutDown flag */
+   private final AtomicBoolean shutdown = new AtomicBoolean(false);
+
+   /** Scheduled executor for graceful shutdown */
+   private ScheduledExecutorService scheduledExecutorService;
+
+   /** Graceful job */
+   private ScheduledFuture scheduledGraceful;
+
+   /** Graceful call back. A non-null value indicates shutdown is prepared but has not started. */
+   private volatile GracefulCallback gracefulCallback;
+
+   /** Cached connection manager */
+   private CachedConnectionManager cachedConnectionManager;
+
+   /** Jndi name */
+   private String jndiName;
+
+   /** Sharable */
+   private boolean sharable;
+
+   /** Enlistment */
+   protected boolean enlistment;
+
+   /** Connectable */
+   protected boolean connectable;
+
+   /** Tracking */
+   protected Boolean tracking;
+
+   /** Enlistment trace */
+   protected ManagedEnlistmentTrace enlistmentTrace;
+
+   /**
+    * Creates a new instance of connection manager.
+    */
+   protected AbstractConnectionManager()
+   {
+      this.log = getLogger();
+      this.scheduledExecutorService = null;
+      this.scheduledGraceful = null;
+      this.gracefulCallback = null;
+   }
+
+   /**
+    * Get the logger.
+    * @return The value
+    */
+   protected abstract CoreLogger getLogger();
+
+   /**
+    * Set the pool.
+    * @param pool the pool
+    */
+   public void setPool(Pool pool)
+   {
+      this.pool = pool;
+   }
+
+   /**
+    * Get the pool.
+    * @return the pool
+    */
+   public Pool getPool()
+   {
+      return pool;
+   }
+
+   /**
+    * Sets cached connection manager.
+    * @param cachedConnectionManager cached connection manager
+    */
+   public void setCachedConnectionManager(CachedConnectionManager cachedConnectionManager)
+   {
+      this.cachedConnectionManager = cachedConnectionManager;
+   }
+
+   /**
+    * Gets cached connection manager.
+    * @return cached connection manager
+    */
+   public CachedConnectionManager getCachedConnectionManager()
+   {
+      return cachedConnectionManager;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean cancelShutdown()
+   {
+      if (scheduledGraceful != null)
+      {
+         boolean result = scheduledGraceful.cancel(false);
+
+         if (result)
+         {
+            shutdown.set(false);
+
+            if (gracefulCallback != null)
+               gracefulCallback.cancel();
+
+            if (pool != null)
+               pool.cancelShutdown();
+
+            scheduledGraceful = null;
+            gracefulCallback = null;
+         }
+         else
+         {
+            return false;
+         }
+      }
+      else if (shutdown.get())
+      {
+         shutdown.set(false);
+
+         if (gracefulCallback != null)
+            gracefulCallback.cancel();
+
+         if (pool != null)
+            pool.cancelShutdown();
+
+         gracefulCallback = null;
+      }
+      else
+      {
+         return false;
+      }
+
+      return true;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void prepareShutdown()
+   {
+      prepareShutdown(0, null);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void prepareShutdown(GracefulCallback cb)
+   {
+      prepareShutdown(0, cb);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void prepareShutdown(int seconds)
+   {
+      prepareShutdown(seconds, null);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void prepareShutdown(int seconds, GracefulCallback cb)
+   {
+      shutdown.set(true);
+
+      // use gracefulCallback as an indicator that shutdown is prepared and not started, for that reason this field
+      // will never be null after preparation and before shutdown (this prevents adding an extra field,
+      // shutdownPrepared, or having to replace shutdown by a state field)
+      if (gracefulCallback == null) 
+         gracefulCallback = cb == null ? EMPTY_CALL_BACK : cb;
+
+      if (pool != null)
+         pool.prepareShutdown();
+
+      if (seconds > 0)
+      {
+         if (scheduledGraceful == null)
+         {
+            if (scheduledExecutorService == null)
+               scheduledExecutorService = Executors.newScheduledThreadPool(1);
+
+            scheduledGraceful =
+               scheduledExecutorService.schedule(new ConnectionManagerShutdown(this), seconds, TimeUnit.SECONDS);
+         }
+      }
+      else
+      {
+         if (pool != null && pool.isIdle())
+         {
+            synchronized (this)
+            {
+               // skip shutdown if there is another thread already taking care of it
+               if (gracefulCallback == null)
+                  return;
+            }
+            shutdown();
+         }
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void shutdown()
+   {
+      getLogger().debugf("%s: shutdown", jndiName);
+      final GracefulCallback gracefulCallback;
+      final ScheduledExecutorService scheduledExecutorService;
+      synchronized (this)
+      {
+         shutdown.set(true);
+         gracefulCallback = this.gracefulCallback;
+         this.gracefulCallback = null;
+         scheduledExecutorService = this.scheduledExecutorService;
+         this.scheduledExecutorService = null;
+      }
+
+      if (pool != null)
+         pool.shutdown();
+
+      if (scheduledExecutorService != null)
+      {
+         if (scheduledGraceful != null && !scheduledGraceful.isDone())
+            scheduledGraceful.cancel(true);
+
+         scheduledGraceful = null;
+         scheduledExecutorService.shutdownNow();
+      }
+
+      if (gracefulCallback != null)
+      {
+         gracefulCallback.done();
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean isShutdown()
+   {
+      return shutdown.get();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public int getDelay()
+   {
+      if (scheduledGraceful != null)
+         return (int)scheduledGraceful.getDelay(TimeUnit.SECONDS);
+
+      if (shutdown.get())
+         return Integer.MIN_VALUE;
+      
+      return Integer.MAX_VALUE;
+   }
+
+   /**
+    * Gets jndi name.
+    * @return jndi name
+    */
+   public String getJndiName()
+   {
+      return jndiName;
+   }
+
+   /**
+    * Sets jndi name.
+    * @param jndiName jndi name
+    */
+   public void setJndiName(String jndiName)
+   {
+      this.jndiName = jndiName;
+   }
+
+   /**
+    * Is sharable
+    * @return The value
+    */
+   public boolean isSharable()
+   {
+      return sharable;
+   }
+
+   /**
+    * Set the sharable flag
+    * @param v The value
+    */
+   public void setSharable(boolean v)
+   {
+      this.sharable = v;
+
+      log.tracef("sharable=%s", sharable);
+   }
+
+   /**
+    * Is enlistment
+    * @return The value
+    */
+   public boolean isEnlistment()
+   {
+      return enlistment;
+   }
+
+   /**
+    * Set the enlistment flag
+    * @param v The value
+    */
+   public void setEnlistment(boolean v)
+   {
+      this.enlistment = v;
+
+      log.tracef("enlistment=%s", enlistment);
+   }
+
+   /**
+    * Is connectable
+    * @return The value
+    */
+   public boolean isConnectable()
+   {
+      return connectable;
+   }
+
+   /**
+    * Set the connectable flag
+    * @param v The value
+    */
+   public void setConnectable(boolean v)
+   {
+      this.connectable = v;
+
+      log.tracef("connectable=%s", connectable);
+   }
+
+   /**
+    * Get tracking
+    * @return The value
+    */
+   public Boolean getTracking()
+   {
+      return tracking;
+   }
+
+   /**
+    * Set the tracking flag
+    * @param v The value
+    */
+   public void setTracking(Boolean v)
+   {
+      this.tracking = v;
+
+      log.tracef("tracking=%s", tracking);
+   }
+
+   /**
+    * Get enlistment trace
+    * @return The value
+    */
+   public ManagedEnlistmentTrace getEnlistmentTrace()
+   {
+      return enlistmentTrace;
+   }
+
+   /**
+    * Set the enlistment trace flag
+    * @param v The value
+    */
+   public void setEnlistmentTrace(ManagedEnlistmentTrace v)
+   {
+      this.enlistmentTrace = v;
+
+      log.tracef("enlistment_trace=%s", enlistmentTrace);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public String getSecurityDomain()
+   {
+      return securityDomain;
+   }
+
+   /**
+    * Sets security domain
+    * @param securityDomain security domain
+    */
+   public void setSecurityDomain(String securityDomain)
+   {
+      this.securityDomain = securityDomain;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public SubjectFactory getSubjectFactory()
+   {
+      return subjectFactory;
+   }
+
+   /**
+    * Sets subject factory.
+    * @param subjectFactory subject factory
+    */
+   public void setSubjectFactory(SubjectFactory subjectFactory)
+   {
+      this.subjectFactory = subjectFactory;
+   }
+
+   /**
+    * Get the flush strategy
+    * @return The value
+    */
+   public FlushStrategy getFlushStrategy()
+   {
+      return flushStrategy;
+   }
+
+   /**
+    * Set the flush strategy
+    * @param v The value
+    */
+   public void setFlushStrategy(FlushStrategy v)
+   {
+      this.flushStrategy = v;
+   }
+
+   /**
+    * Gets managed connection factory.
+    * @return managed connection factory
+    */
+   public javax.resource.spi.ManagedConnectionFactory getManagedConnectionFactory()
+   {
+      if (pool == null)
+      {
+         log.tracef("No pooling strategy found! for connection manager : %s", this);
+         return null;
+      }
+      else
+      {
+         return pool.getManagedConnectionFactory();
+      }
+
+   }
+
+   /**
+    * Set the number of allocation retries
+    * @param number retry number
+    */
+   public void setAllocationRetry(int number)
+   {
+      if (number >= 0)
+         allocationRetry = number;
+   }
+
+   /**
+    * Get the number of allocation retries
+    * @return The number of retries
+    */
+   public int getAllocationRetry()
+   {
+      return allocationRetry;
+   }
+
+   /**
+    * Set the wait time between each allocation retry
+    * @param millis wait in ms
+    */
+   public void setAllocationRetryWaitMillis(long millis)
+   {
+      if (millis > 0)
+         allocationRetryWaitMillis = millis;
+   }
+
+   /**
+    * Get the wait time between each allocation retry
+    * @return The millis
+    */
+   public long getAllocationRetryWaitMillis()
+   {
+      return allocationRetryWaitMillis;
+   }
+
+   /**
+    * Public for use in testing pooling functionality by itself.
+    * called by both allocateConnection and reconnect.
+    *
+    * @param subject a Subject value
+    * @param cri a ConnectionRequestInfo value
+    * @return a ManagedConnection value
+    * @exception ResourceException if an error occurs
+    */
+   public ConnectionListener getManagedConnection(Subject subject, ConnectionRequestInfo cri) throws ResourceException
+   {
+      return getManagedConnection(null, subject, cri);
+   }
+
+   /**
+    * Get the managed connection from the pool.
+    *
+    * @param transaction the transaction for track by transaction
+    * @param subject the subject
+    * @param cri the ConnectionRequestInfo
+    * @return a managed connection
+    * @exception ResourceException if an error occurs
+    */
+   protected ConnectionListener getManagedConnection(Transaction transaction, Subject subject,
+         ConnectionRequestInfo cri) throws ResourceException
+   {
+      Exception failure = null;
+
+      if (shutdown.get())
+      {
+         throw new ResourceException(bundle.connectionManagerIsShutdown(jndiName));
+      }
+
+      // First attempt
+      boolean isInterrupted = Thread.interrupted();
+      boolean innerIsInterrupted = false;
+      try
+      {
+         return pool.getConnection(transaction, subject, cri);
+      }
+      catch (ResourceException e)
+      {
+         failure = e;
+
+         // Retry?
+         if (allocationRetry != 0 || e instanceof RetryableException)
+         {
+            int to = allocationRetry;
+
+            if (allocationRetry == 0 && e instanceof RetryableException)
+               to = 1;
+
+            for (int i = 0; i < to; i++)
+            {
+               if (shutdown.get())
+               {
+                  throw new ResourceException(bundle.connectionManagerIsShutdown(jndiName));
+               }
+
+               log.tracef("%s: Attempting allocation retry (%s, %s, %s)", jndiName, transaction, subject, cri);
+
+               if (Thread.currentThread().isInterrupted())
+               {
+                  Thread.interrupted();
+                  innerIsInterrupted = true;
+               }
+
+               try
+               {
+                  if (allocationRetryWaitMillis != 0)
+                  {
+                     Thread.sleep(allocationRetryWaitMillis);
+                  }
+
+                  return pool.getConnection(transaction, subject, cri);
+               }
+               catch (ResourceException re)
+               {
+                  failure = re;
+               }
+               catch (InterruptedException ie)
+               {
+                  failure = ie;
+                  innerIsInterrupted = true;
+               }
+            }
+         }
+      }
+      catch (Exception e)
+      {
+         failure = e;
+      }
+      finally
+      {
+         if (isInterrupted || innerIsInterrupted)
+         {
+            Thread.currentThread().interrupt();
+      
+            if (innerIsInterrupted)
+               throw new ResourceException(bundle.getManagedConnectionRetryWaitInterrupted(jndiName), failure);
+         }
+      }
+
+      // If we get here all retries failed, throw the lastest failure
+      throw new ResourceException(bundle.unableGetManagedConnection(jndiName), failure);
+   }
+
+   /**
+    * Kill given connection listener wrapped connection instance.
+    * @param bcl connection listener that wraps connection
+    * @param kill kill connection or not
+    */
+   public void returnManagedConnection(org.jboss.jca.core.api.connectionmanager.listener.ConnectionListener bcl,
+                                       boolean kill)
+   {
+      // Hack - We know that we can type cast it
+      ConnectionListener cl = (ConnectionListener)bcl;
+
+      Pool localStrategy = cl.getPool();
+      if (localStrategy != pool || shutdown.get())
+      {
+         kill = true;
+      }
+
+      try
+      {
+         if (!kill && cl.getState().equals(ConnectionState.NORMAL))
+         {
+            cl.tidyup();
+         }
+      }
+      catch (Throwable t)
+      {
+         log.errorDuringTidyUpConnection(cl, t);
+         kill = true;
+      }
+
+      try
+      {
+         localStrategy.returnConnection(cl, kill);
+      }
+      catch (ResourceException re)
+      {
+         // We can receive notification of an error on the connection
+         // before it has been assigned to the pool. Reduce the noise for
+         // these errors
+         if (kill)
+         {
+            log.debug("ResourceException killing connection", re);
+         }
+         else
+         {
+            log.resourceExceptionReturningConnection(cl.getManagedConnection(), re);
+         }
+      }
+      catch (Exception e)
+      {
+         try
+         {
+            // Something is very wrong, so lets set the state up-front
+            if (cl.getState().equals(ConnectionState.NORMAL))
+               cl.setState(ConnectionState.DESTROY);
+
+            localStrategy.returnConnection(cl, true);
+         }
+         catch (Throwable t)
+         {
+            log.throwableReturningConnection(cl.getManagedConnection(), t);
+         }
+      }
+
+      if (shutdown.get() && pool.isIdle())
+      {
+         synchronized (this)
+         {
+            // skip shutdown if there is another thread already taking care of it
+            if (gracefulCallback == null)
+               return;
+         }
+         shutdown();
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public Object allocateConnection(ManagedConnectionFactory mcf, ConnectionRequestInfo cri) throws ResourceException
+   {
+      //Check for pooling!
+      if (pool == null || shutdown.get())
+      {
+         throw new ResourceException(bundle.tryingUseConnectionFactoryShutDown(jndiName));
+      }
+
+      //it is an explicit spec requirement that equals be used for matching rather than ==.
+      if (!pool.getManagedConnectionFactory().equals(mcf))
+      {
+         throw new ResourceException(
+            bundle.wrongManagedConnectionFactorySentToAllocateConnection(pool.getManagedConnectionFactory(), mcf));
+      }
+
+      // Pick a managed connection from the pool
+      Subject subject = getSubject();
+      ConnectionListener cl = getManagedConnection(subject, cri);
+
+      // Tell each connection manager the managed connection is active
+      reconnectManagedConnection(cl);
+
+      // Ask the managed connection for a connection
+      Object connection = null;
+      try
+      {
+         connection = cl.getManagedConnection().getConnection(subject, cri);
+      }
+      catch (Throwable t)
+      {
+         try
+         {
+            managedConnectionDisconnected(cl);
+         }
+         catch (ResourceException re)
+         {
+            log.tracef("Get exception from managedConnectionDisconnected, maybe delist() have problem %s", re);
+            returnManagedConnection(cl, true);
+         }
+         throw new ResourceException(bundle.uncheckedThrowableInManagedConnectionGetConnection(cl), t);
+      }
+
+      // Associate managed connection with the connection
+      registerAssociation(cl, connection);
+
+      if (cachedConnectionManager != null)
+      {
+         cachedConnectionManager.registerConnection(this, cl, connection);
+      }
+
+      return connection;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void associateConnection(Object connection, ManagedConnectionFactory mcf, ConnectionRequestInfo cri)
+      throws ResourceException
+   {
+      associateManagedConnection(connection, mcf, cri);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public ManagedConnection associateManagedConnection(Object connection, ManagedConnectionFactory mcf,
+                                                       ConnectionRequestInfo cri)
+      throws ResourceException
+   {
+      // Check for pooling!
+      if (pool == null || shutdown.get())
+      {
+         throw new ResourceException(bundle.tryingUseConnectionFactoryShutDown(jndiName));
+      }
+
+      // It is an explicit spec requirement that equals be used for matching rather than ==.
+      if (!pool.getManagedConnectionFactory().equals(mcf))
+      {
+         throw new ResourceException(
+            bundle.wrongManagedConnectionFactorySentToAllocateConnection(pool.getManagedConnectionFactory(), mcf));
+      }
+
+      if (connection == null)
+         throw new ResourceException(bundle.connectionIsNull());
+
+      // Pick a managed connection from the pool
+      Subject subject = getSubject();
+      ConnectionListener cl = getManagedConnection(subject, cri);
+
+      // Tell each connection manager the managed connection is active
+      reconnectManagedConnection(cl);
+
+      // Associate managed connection with the connection
+      cl.getManagedConnection().associateConnection(connection);
+      registerAssociation(cl, connection);
+
+      if (cachedConnectionManager != null)
+      {
+         cachedConnectionManager.registerConnection(this, cl, connection);
+      }
+
+      return cl.getManagedConnection();
+   }
+ 
+   /**
+    * {@inheritDoc}
+    */
+   public boolean dissociateManagedConnection(Object connection, ManagedConnection mc, ManagedConnectionFactory mcf)
+      throws ResourceException
+   {
+      if (connection == null || mc == null || mcf == null)
+         throw new ResourceException(bundle.unableToFindConnectionListener());
+
+      ConnectionListener cl = getPool().findConnectionListener(mc, connection);
+
+      if (cl != null)
+      {
+         log.tracef("DissociateManagedConnection: cl=%s, connection=%s", cl, connection);
+
+         if (getCachedConnectionManager() != null)
+         {
+            try
+            {
+               getCachedConnectionManager().unregisterConnection(this, cl, connection);
+            }
+            catch (Throwable t)
+            {
+               log.debug("Throwable from unregisterConnection", t);
+            }
+         }
+
+         unregisterAssociation(cl, connection);
+
+         if (cl.getNumberOfConnections() == 0)
+         {
+            log.tracef("DissociateManagedConnection: Returning cl=%s", cl);
+
+            cl.dissociate();
+
+            log.tracef("DissociateManagedConnection: isManagedConnectionFree=%s", cl.isManagedConnectionFree());
+
+            if (cl.isManagedConnectionFree())
+            {
+               // TODO - clean up TSR
+
+               returnManagedConnection(cl, false);
+
+               return true;
+            }
+         }
+      }
+      else
+      {
+         throw new ResourceException(bundle.unableToFindConnectionListener());
+      }
+
+      return false;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void inactiveConnectionClosed(Object connection, ManagedConnectionFactory mcf)
+   {
+      // We don't track inactive connections
+   }
+
+   /**
+    * Unregister association.
+    * @param cl connection listener
+    * @param c connection
+    */
+   //does NOT put the mc back in the pool if no more handles. Doing so would introduce a race condition
+   //whereby the mc got back in the pool while still enlisted in the tx.
+   //The mc could be checked out again and used before the delist occured.
+   public void unregisterAssociation(ConnectionListener cl, Object c)
+   {
+      cl.unregisterConnection(c);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void lazyEnlist(ManagedConnection mc) throws ResourceException
+   {
+      // Nothing by default
+   }
+
+   /**
+    * Invoked to reassociate a managed connection.
+    *
+    * @param cl the managed connection
+    * @throws ResourceException for exception
+    */
+   protected void reconnectManagedConnection(ConnectionListener cl) throws ResourceException
+   {
+      try
+      {
+         managedConnectionReconnected(cl);
+      }
+      catch (Throwable t)
+      {
+         disconnectManagedConnection(cl);
+         throw new ResourceException(bundle.uncheckedThrowableInManagedConnectionReconnected(cl), t);
+      }
+   }
+
+   /**
+    * Invoked when a managed connection is no longer associated
+    *
+    * @param cl the managed connection
+    */
+   protected void disconnectManagedConnection(ConnectionListener cl)
+   {
+      try
+      {
+         managedConnectionDisconnected(cl);
+      }
+      catch (Throwable t)
+      {
+         log.uncheckedThrowableInManagedConnectionDisconnected(cl, t);
+      }
+   }
+
+   /**
+    * For polymorphism.
+    * 
+    *
+    * Do not invoke directly, use reconnectManagedConnection
+    * which does the relevent exception handling
+    * @param cl connection listener
+    * @throws ResourceException for exception
+    */
+   protected void managedConnectionReconnected(ConnectionListener cl) throws ResourceException
+   {
+      //Nothing as default
+   }
+
+   /**
+    * For polymorphism.
+    * 
+    *
+    * Do not invoke directly, use disconnectManagedConnection
+    * which does the relevent exception handling
+    * @param cl connection listener
+    * @throws ResourceException for exception
+    */
+   protected void managedConnectionDisconnected(ConnectionListener cl) throws ResourceException
+   {
+      //Nothing as default
+   }
+
+   /**
+    * Register connection with connection listener.
+    * @param cl connection listener
+    * @param c connection
+    * @throws ResourceException exception
+    */
+   private void registerAssociation(ConnectionListener cl, Object c) throws ResourceException
+   {
+      cl.registerConnection(c);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public abstract void transactionStarted(Collection conns) throws SystemException;
+
+   /**
+    * {@inheritDoc}
+    */
+   public abstract boolean isTransactional();
+
+   /**
+    * {@inheritDoc}
+    */
+   public abstract TransactionIntegration getTransactionIntegration();
+
+   /**
+    * Get a subject
+    * @return The subject
+    */
+   private Subject getSubject()
+   {
+      Subject subject = null;
+
+      if (subjectFactory != null && securityDomain != null)
+      {
+         subject = SecurityActions.createSubject(subjectFactory, securityDomain);
+
+         Set credentials = SecurityActions.getPasswordCredentials(subject);
+         if (credentials != null && credentials.size() > 0)
+         {
+            ManagedConnectionFactory pcMcf = getManagedConnectionFactory();
+            for (PasswordCredential pc : credentials)
+            {
+               pc.setManagedConnectionFactory(pcMcf);
+            }
+         }
+      }
+
+      log.tracef("Subject: %s", subject);
+
+      return subject;
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ConnectionManager.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ConnectionManager.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ConnectionManager.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,144 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2014, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager;
+
+import org.jboss.jca.core.api.connectionmanager.ccm.CachedConnectionManager;
+import org.jboss.jca.core.connectionmanager.listener.ConnectionCacheListener;
+import org.jboss.jca.core.connectionmanager.listener.ConnectionListener;
+import org.jboss.jca.core.connectionmanager.pool.api.Pool;
+import org.jboss.jca.core.connectionmanager.pool.mcp.ManagedConnectionPool;
+import org.jboss.jca.core.spi.graceful.GracefulShutdown;
+import org.jboss.jca.core.spi.security.SubjectFactory;
+import org.jboss.jca.core.spi.transaction.TransactionIntegration;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.ManagedConnection;
+
+/**
+ * Internal connection manager contract.
+ * 
+ * 
+ *    Responsible for managing cached connections over transactional 
+ *    components via {@link ConnectionCacheListener} 
+ *    Responsible for managing connection instances using event listener 
+ *  
+ *   
 
+ * @author Gurkan Erdogdu  
+ * @author Jesper Pedersen  
+ */
+public interface ConnectionManager extends
+   org.jboss.jca.core.api.connectionmanager.ConnectionManager,
+   ConnectionCacheListener,
+   GracefulShutdown
+{
+   /**
+    * Get the pool.
+    * @return the pool
+    */
+   public Pool getPool();
+
+   /**
+    * Gets cached connection manager
+    * @return The cached connection manager
+    */
+   public CachedConnectionManager getCachedConnectionManager();
+
+   /**
+    * Get the number of allocation retries
+    * @return The number of retries
+    */
+   public int getAllocationRetry();
+
+   /**
+    * Get the wait time between each allocation retry
+    * @return The millis
+    */
+   public long getAllocationRetryWaitMillis();
+
+   /**
+    * Get the JNDI name
+    * @return The value
+    */
+   public String getJndiName();
+
+   /**
+    * Set the JNDI name
+    * @param value The value
+    */
+   public void setJndiName(String value);
+
+   /**
+    * Get the security domain.
+    * @return The value
+    */
+   public String getSecurityDomain();
+
+   /**
+    * Get the subject factory
+    * @return The value
+    */
+   public SubjectFactory getSubjectFactory();
+
+   /**
+    * Unregister association.
+    * @param cl connection listener
+    * @param c connection
+    */
+   public void unregisterAssociation(ConnectionListener cl, Object c);
+
+   /**
+    * Create a managed connection listener for the managed connection.
+    * 
+    * @param managedConnection the managed connection
+    * @param mcp the managed connection pool
+    * @return a new connection event listener
+    * @throws ResourceException for any error
+    */
+   public ConnectionListener createConnectionListener(ManagedConnection managedConnection, ManagedConnectionPool mcp)
+      throws ResourceException;
+
+   /**
+    * Determine whether there connection is a transactional.
+    *
+    * @return whether it is a transactional or not
+    */
+   public boolean isTransactional();
+
+   /**
+    * Get the transaction integration.
+    * 
+    * @return the transaction integration
+    */
+   public TransactionIntegration getTransactionIntegration();
+
+   /**
+    * Is sharable
+    * @return The value
+    */
+   public boolean isSharable();
+
+   /**
+    * Is enlistment
+    * @return The value
+    */
+   public boolean isEnlistment();
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ConnectionManagerFactory.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ConnectionManagerFactory.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ConnectionManagerFactory.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,312 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2008-2009, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager;
+
+import org.jboss.jca.common.api.metadata.common.FlushStrategy;
+import org.jboss.jca.core.api.connectionmanager.ccm.CachedConnectionManager;
+import org.jboss.jca.core.api.management.ManagedEnlistmentTrace;
+import org.jboss.jca.core.connectionmanager.notx.NoTxConnectionManagerImpl;
+import org.jboss.jca.core.connectionmanager.pool.api.Pool;
+import org.jboss.jca.core.connectionmanager.tx.TxConnectionManagerImpl;
+import org.jboss.jca.core.spi.security.SubjectFactory;
+import org.jboss.jca.core.spi.transaction.TransactionIntegration;
+
+import javax.resource.spi.TransactionSupport.TransactionSupportLevel;
+import javax.transaction.TransactionManager;
+
+/**
+ * The connection manager factory.
+ * @author Jesper Pedersen 
+ */
+public class ConnectionManagerFactory
+{
+   /**
+    * Constructor
+    */
+   public ConnectionManagerFactory()
+   {
+   }
+
+   /**
+    * Create a connection manager
+    * @param tsl The transaction support level
+    * @param pool The pool for the connection manager
+    * @param subjectFactory The subject factory
+    * @param securityDomain The security domain 
+    * @param useCcm Should the CCM be used
+    * @param ccm The cached connection manager
+    * @param sharable Enable sharable connections
+    * @param enlistment Enable enlistment connections
+    * @param connectable Enable connectable connections
+    * @param tracking The tracking status
+    * @param flushStrategy The flush strategy
+    * @param allocationRetry The allocation retry value
+    * @param allocationRetryWaitMillis The allocation retry millis value
+    * @return The connection manager instance
+    */
+   public NoTxConnectionManager createNonTransactional(final TransactionSupportLevel tsl,
+                                                       final Pool pool,
+                                                       final SubjectFactory subjectFactory,
+                                                       final String securityDomain,
+                                                       final boolean useCcm,
+                                                       final CachedConnectionManager ccm,
+                                                       final boolean sharable,
+                                                       final boolean enlistment,
+                                                       final boolean connectable,
+                                                       final Boolean tracking,
+                                                       final FlushStrategy flushStrategy,
+                                                       final Integer allocationRetry,
+                                                       final Long allocationRetryWaitMillis)
+   {
+      if (tsl == null)
+         throw new IllegalArgumentException("TransactionSupportLevel is null");
+
+      if (pool == null)
+         throw new IllegalArgumentException("Pool is null");
+
+      if (flushStrategy == null)
+         throw new IllegalArgumentException("FlushStrategy is null");
+
+      NoTxConnectionManagerImpl cm = null;
+
+      switch (tsl)
+      {
+         case NoTransaction:
+            cm = new NoTxConnectionManagerImpl();
+            break;
+
+         case LocalTransaction:
+            throw new IllegalArgumentException("Transactional connection manager not supported");
+
+         case XATransaction:
+            throw new IllegalArgumentException("Transactional connection manager not supported");
+
+         default:
+            throw new IllegalArgumentException("Unknown transaction support level " + tsl);
+      }
+
+      setProperties(cm, pool,
+                    subjectFactory, securityDomain, 
+                    useCcm, ccm,
+                    sharable,
+                    enlistment,
+                    connectable,
+                    tracking,
+                    null,
+                    flushStrategy,
+                    allocationRetry, allocationRetryWaitMillis, 
+                    null);
+      setNoTxProperties(cm);
+
+      return cm;
+   }
+
+   /**
+    * Create a transactional connection manager
+    * @param tsl The transaction support level
+    * @param pool The pool for the connection manager
+    * @param subjectFactory The subject factory
+    * @param securityDomain The security domain 
+    * @param useCcm Should the CCM be used
+    * @param ccm The cached connection manager
+    * @param sharable Enable sharable connections
+    * @param enlistment Enable enlistment connections
+    * @param connectable Enable connectable connections
+    * @param tracking The tracking status
+    * @param enlistmentTrace The enlistment trace
+    * @param flushStrategy The flush strategy
+    * @param allocationRetry The allocation retry value
+    * @param allocationRetryWaitMillis The allocation retry millis value
+    * @param txIntegration The transaction manager integration
+    * @param interleaving Enable interleaving
+    * @param xaResourceTimeout The transaction timeout for XAResource
+    * @param isSameRMOverride Should isSameRM be overridden
+    * @param wrapXAResource Should XAResource be wrapped
+    * @param padXid Should Xids be padded
+    * @return The connection manager instance
+    */
+   public TxConnectionManager createTransactional(final TransactionSupportLevel tsl,
+                                                  final Pool pool,
+                                                  final SubjectFactory subjectFactory,
+                                                  final String securityDomain,
+                                                  final boolean useCcm,
+                                                  final CachedConnectionManager ccm,
+                                                  final boolean sharable,
+                                                  final boolean enlistment,
+                                                  final boolean connectable,
+                                                  final Boolean tracking,
+                                                  final ManagedEnlistmentTrace enlistmentTrace,
+                                                  final FlushStrategy flushStrategy,
+                                                  final Integer allocationRetry,
+                                                  final Long allocationRetryWaitMillis,
+                                                  final TransactionIntegration txIntegration,
+                                                  final Boolean interleaving,
+                                                  final Integer xaResourceTimeout,
+                                                  final Boolean isSameRMOverride,
+                                                  final Boolean wrapXAResource,
+                                                  final Boolean padXid)
+   {
+      if (tsl == null)
+         throw new IllegalArgumentException("TransactionSupportLevel is null");
+
+      if (pool == null)
+         throw new IllegalArgumentException("Pool is null");
+
+      if (txIntegration == null)
+         throw new IllegalArgumentException("TransactionIntegration is null");
+
+      if (flushStrategy == null)
+         throw new IllegalArgumentException("FlushStrategy is null");
+
+      TxConnectionManagerImpl cm = null;
+
+      switch (tsl)
+      {
+         case NoTransaction:
+            throw new IllegalArgumentException("Non transactional connection manager not supported");
+
+         case LocalTransaction:
+            cm = new TxConnectionManagerImpl(txIntegration, true);
+            break;
+
+         case XATransaction:
+            cm = new TxConnectionManagerImpl(txIntegration, false);
+            break;
+
+         default:
+            throw new IllegalArgumentException("Unknown transaction support level " + tsl);
+      }
+
+      setProperties(cm, pool, 
+                    subjectFactory, securityDomain, 
+                    useCcm, ccm,
+                    sharable,
+                    enlistment,
+                    connectable,
+                    tracking,
+                    enlistmentTrace,
+                    flushStrategy,
+                    allocationRetry, allocationRetryWaitMillis,
+                    txIntegration.getTransactionManager());
+      setTxProperties(cm, interleaving, xaResourceTimeout, isSameRMOverride, wrapXAResource, padXid);
+
+      return cm;
+   }
+
+   /**
+    * Common properties
+    * @param cm The connection manager
+    * @param pool The pool
+    * @param subjectFactory The subject factory
+    * @param securityDomain The security domain
+    * @param useCcm Should the CCM be used
+    * @param ccm The cached connection manager
+    * @param sharable Enable sharable connections
+    * @param enlistment Enable enlistment connections
+    * @param connectable Enable connectable connections
+    * @param tracking The tracking status
+    * @param enlistmentTrace The enlistment trace
+    * @param flushStrategy The flush strategy
+    * @param allocationRetry The allocation retry value
+    * @param allocationRetryWaitMillis The allocation retry millis value
+    * @param tm The transaction manager
+    */
+   private void setProperties(AbstractConnectionManager cm,
+                              Pool pool,
+                              SubjectFactory subjectFactory,
+                              String securityDomain,
+                              boolean useCcm,
+                              CachedConnectionManager ccm,
+                              boolean sharable,
+                              boolean enlistment,
+                              boolean connectable,
+                              Boolean tracking,
+                              ManagedEnlistmentTrace enlistmentTrace,
+                              FlushStrategy flushStrategy,
+                              Integer allocationRetry,
+                              Long allocationRetryWaitMillis,
+                              TransactionManager tm)
+   {
+      pool.setConnectionManager(cm);
+      cm.setPool(pool);
+
+      cm.setSubjectFactory(subjectFactory);
+      cm.setSecurityDomain(securityDomain);
+
+      cm.setFlushStrategy(flushStrategy);
+
+      if (allocationRetry != null)
+         cm.setAllocationRetry(allocationRetry.intValue());
+
+      if (allocationRetryWaitMillis != null)
+         cm.setAllocationRetryWaitMillis(allocationRetryWaitMillis.longValue());
+
+      if (useCcm)
+         cm.setCachedConnectionManager(ccm);
+
+      cm.setSharable(sharable);
+      cm.setEnlistment(enlistment);
+      cm.setConnectable(connectable);
+      cm.setTracking(tracking);
+      cm.setEnlistmentTrace(enlistmentTrace);
+   }
+
+   /**
+    * NoTxConnectionManager properties
+    * @param cm The connection manager
+    */
+   private void setNoTxProperties(NoTxConnectionManagerImpl cm)
+   {
+   }
+
+   /**
+    * TxConnectionManager properties
+    * @param cm The connection manager
+    * @param interleaving Enable interleaving
+    * @param xaResourceTimeout The transaction timeout for XAResource
+    * @param isSameRMOverride Should isSameRM be overridden
+    * @param wrapXAResource Should XAResource be wrapped
+    * @param padXid Should Xids be padded
+    */
+   private void setTxProperties(TxConnectionManagerImpl cm,
+                                Boolean interleaving,
+                                Integer xaResourceTimeout,
+                                Boolean isSameRMOverride,
+                                Boolean wrapXAResource,
+                                Boolean padXid)
+   {
+      if (interleaving != null)
+         cm.setInterleaving(interleaving.booleanValue());
+
+      if (xaResourceTimeout != null)
+         cm.setXAResourceTimeout(xaResourceTimeout.intValue());
+
+      cm.setIsSameRMOverride(isSameRMOverride);
+
+      if (wrapXAResource != null)
+         cm.setWrapXAResource(wrapXAResource.booleanValue());
+
+      if (padXid != null)
+         cm.setPadXid(padXid.booleanValue());
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ConnectionManagerShutdown.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ConnectionManagerShutdown.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ConnectionManagerShutdown.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,49 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2014, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager;
+
+/**
+ * Shutdown a ConnectionManager
+ * @author Jesper Pedersen 
+ */
+class ConnectionManagerShutdown implements Runnable
+{
+   private ConnectionManager cm;
+
+   /**
+    * Constructor
+    * @param cm The connection manager
+    */
+   ConnectionManagerShutdown(ConnectionManager cm)
+   {
+      this.cm = cm;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void run()
+   {
+      cm.shutdown();
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ConnectionRecord.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ConnectionRecord.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ConnectionRecord.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,77 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2006, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager;
+
+import org.jboss.jca.core.connectionmanager.listener.ConnectionListener;
+
+/**
+ * Information about a connection.
+ *
+ * @author David Jencks 
+ * @author Adrian Brock 
+ * @author Gurkan Erdogdu  
+ * @author Jesper Pedersen  
+ */
+public class ConnectionRecord 
+{
+   private ConnectionListener connectionListener;
+   private final Object connection;
+   
+   /**
+    * Creates a new connection record.
+    * @param cl connection listener
+    * @param connection connection handle
+    */
+   public ConnectionRecord (final org.jboss.jca.core.api.connectionmanager.listener.ConnectionListener cl, 
+                            final Object connection)
+   {
+      this.connectionListener = (ConnectionListener)cl;
+      this.connection = connection;
+   }
+
+   /**
+    * Get the connection listener
+    * @return The listener
+    */
+   public ConnectionListener getConnectionListener()
+   {
+      return connectionListener;
+   }
+
+   /**
+    * Set the connection listener
+    * @param cl The listener
+    */
+   void setConnectionListener(ConnectionListener cl)
+   {
+      this.connectionListener = cl;
+   }
+
+   /**
+    * Get the connection
+    * @return The connection
+    */
+   public Object getConnection()
+   {
+      return connection;
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/NoTxConnectionManager.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/NoTxConnectionManager.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/NoTxConnectionManager.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,31 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2010, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager;
+
+/**
+ * Internal connection manager contract for non-transactional contexts.
+ *
+ * @author Jesper Pedersen  
+ */
+public interface NoTxConnectionManager extends ConnectionManager
+{
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/SecurityActions.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/SecurityActions.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/SecurityActions.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,85 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2014, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager;
+
+import org.jboss.jca.core.spi.security.SubjectFactory;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Set;
+
+import javax.resource.spi.security.PasswordCredential;
+import javax.security.auth.Subject;
+
+/**
+ * Privileged Blocks
+ * @author Jesper Pedersen 
+ */
+class SecurityActions
+{ 
+   /**
+    * Constructor
+    */
+   private SecurityActions()
+   {
+   }
+
+   /**
+    * Get a Subject instance
+    * @param subjectFactory The subject factory
+    * @param domain The domain
+    * @return The instance
+    */
+   static Subject createSubject(final SubjectFactory subjectFactory, final String domain)
+   {
+      if (System.getSecurityManager() == null)
+         return subjectFactory.createSubject(domain);
+
+      return AccessController.doPrivileged(new PrivilegedAction() 
+      {
+         public Subject run()
+         {
+            return subjectFactory.createSubject(domain);
+         }
+      });
+   }
+
+   /**
+    * Get the PasswordCredential from the Subject
+    * @param subject The subject
+    * @return The instances
+    */
+   static Set getPasswordCredentials(final Subject subject)
+   {
+      if (System.getSecurityManager() == null)
+         return subject.getPrivateCredentials(PasswordCredential.class);
+
+      return AccessController.doPrivileged(new PrivilegedAction>() 
+      {
+         public Set run()
+         {
+            return subject.getPrivateCredentials(PasswordCredential.class);
+         }
+      });
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/TxConnectionManager.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/TxConnectionManager.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/TxConnectionManager.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,79 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2011, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager;
+
+import org.jboss.jca.core.spi.transaction.TransactionTimeoutConfiguration;
+
+/**
+ * Internal connection manager contract for transactional contexts.
+ * 
+ * 
+ *    Responsible for managing transaction operations via {@link TransactionTimeoutConfiguration} 
+ *  
+ *                
 
+ *
+ * @author Jesper Pedersen  
+ */
+public interface TxConnectionManager extends ConnectionManager, TransactionTimeoutConfiguration
+{
+   /**
+    * Get the interleaving status
+    * @return True if interleaving; otherwise false
+    */
+   public boolean isInterleaving();
+
+   /**
+    * Get the local transaction status
+    * @return True if local transactions; false if XA
+    */
+   public boolean isLocalTransactions();
+
+   /**
+    * Get the XA resource transaction time out in seconds
+    * @return The value
+    */
+   public int getXAResourceTimeout();
+
+   /**
+    * Get the IsSameRMOverride status
+    * @return null if no override; else true or false
+    */
+   public Boolean getIsSameRMOverride();
+
+   /**
+    * Get the wrap XAResource status
+    * @return True if XAResource instances are wrapped; otherwise false
+    */
+   public boolean getWrapXAResource();
+
+   /**
+    * Get the PadXid status
+    * @return True if Xids are padded; otherwise false
+    */
+   public boolean getPadXid();
+
+   /**
+    * Is allow marked for rollback enabled
+    * @return True if set, otherwise false
+    */
+   public boolean isAllowMarkedForRollback();
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ccm/CachedConnectionManagerImpl.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ccm/CachedConnectionManagerImpl.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ccm/CachedConnectionManagerImpl.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,741 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2015, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager.ccm;
+
+import org.jboss.jca.core.CoreBundle;
+import org.jboss.jca.core.CoreLogger;
+import org.jboss.jca.core.api.connectionmanager.ccm.CachedConnectionManager;
+import org.jboss.jca.core.connectionmanager.ConnectionRecord;
+import org.jboss.jca.core.connectionmanager.listener.ConnectionCacheListener;
+import org.jboss.jca.core.connectionmanager.listener.ConnectionListener;
+import org.jboss.jca.core.connectionmanager.transaction.TransactionSynchronizer;
+import org.jboss.jca.core.spi.transaction.TransactionIntegration;
+import org.jboss.jca.core.spi.transaction.TxUtils;
+import org.jboss.jca.core.tracer.Tracer;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.WeakHashMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.resource.ResourceException;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import javax.transaction.TransactionSynchronizationRegistry;
+
+import org.jboss.logging.Logger;
+import org.jboss.logging.Messages;
+
+/**
+ * CacheConnectionManager.
+ *
+ * @author Jesper Pedersen 
+ */
+public class CachedConnectionManagerImpl implements CachedConnectionManager
+{
+   /** Log instance */
+   private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, 
+                                                           CachedConnectionManager.class.getName());
+
+   /** The bundle */
+   private static CoreBundle bundle = Messages.getBundle(CoreBundle.class);
+   
+   /** Debugging flag */
+   private boolean debug = false;
+
+   /** Enabled error handling for debugging */
+   private boolean error = false;
+
+   /** Ignore unknown connections */
+   private boolean ignoreConnections = false;
+
+   /** Transaction integration */
+   private TransactionIntegration transactionIntegration;
+
+   /**
+    * ThreadLocal that holds current calling meta-programming aware
+    * object, used in case someone is idiotic enough to cache a
+    * connection between invocations.and want the spec required
+    * behavior of it getting hooked up to an appropriate
+    * ManagedConnection on each method invocation.
+    */
+   private final ThreadLocal> currentObjects =
+      new ThreadLocal>();
+
+   /**
+    * The variable objectToConnectionManagerMap holds the
+    * map of meta-aware object to set of connections it holds, used by
+    * the idiot spec compliant behavior.
+    */
+   private final ConcurrentMap>>
+   objectToConnectionManagerMap = new ConcurrentHashMap>>();
+
+   /**
+    * Connection stacktraces
+    */
+   private final Map connectionStackTraces = new WeakHashMap();
+
+   /**
+    * Creates a new instance.
+    * @param transactionIntegration The transaction integration
+    */
+   public CachedConnectionManagerImpl(TransactionIntegration transactionIntegration)
+   {
+      if (transactionIntegration == null)
+         throw new IllegalArgumentException("TransactionIntegration is null");
+
+      this.transactionIntegration = transactionIntegration;
+   }
+
+   /**
+    * Gets transaction manager.
+    * @return transaction manager
+    */
+   public TransactionManager getTransactionManager()
+   {
+      return transactionIntegration.getTransactionManager();
+   }
+
+   /**
+    * Gets transaction synchronization registry
+    * @return TransactionSynchronizationRegistry
+    */
+   public TransactionSynchronizationRegistry getTransactionSynchronizationRegistry()
+   {
+      return transactionIntegration.getTransactionSynchronizationRegistry();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean isDebug()
+   {
+      return debug;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void setDebug(boolean v)
+   {
+      debug = v;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean isError()
+   {
+      return error;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void setError(boolean v)
+   {
+      error = v;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean isIgnoreUnknownConnections()
+   {
+      return ignoreConnections;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void setIgnoreUnknownConnections(boolean v)
+   {
+      ignoreConnections = v;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void start()
+   {
+      if (transactionIntegration.getUserTransactionRegistry() != null)
+         transactionIntegration.getUserTransactionRegistry().addListener(this);
+
+      log.debugf("start: %s", this.toString());
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void stop()
+   {
+      log.debugf("stop: %s", this.toString());
+
+      if (transactionIntegration.getUserTransactionRegistry() != null)
+         transactionIntegration.getUserTransactionRegistry().removeListener(this);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void userTransactionStarted() throws SystemException
+   {
+      KeyConnectionAssociation key = peekMetaAwareObject();
+
+      log.tracef("user tx started, key: %s", key);
+
+      if (key != null)
+      {
+         ConcurrentMap> cmToConnectionsMap =
+            key.getCMToConnectionsMap();
+
+         Iterator>> cmToConnectionsMapIterator =
+            cmToConnectionsMap.entrySet().iterator();
+
+         while (cmToConnectionsMapIterator.hasNext())
+         {
+            Entry> entry =
+               cmToConnectionsMapIterator.next();
+
+            ConnectionCacheListener cm = entry.getKey();
+            CopyOnWriteArrayList conns = entry.getValue();
+
+            if (Tracer.isEnabled())
+            {
+               for (ConnectionRecord cr : conns)
+               {
+                  ConnectionListener cl = (ConnectionListener)cr.getConnectionListener();
+                  Tracer.ccmUserTransaction(cl.getPool().getName(), cl.getManagedConnectionPool(),
+                                            cl, cr.getConnection(), key.toString());
+               }
+            }
+
+            cm.transactionStarted(conns);
+         }
+      }
+   }
+
+   /**
+    *
+    * @return stack last meta-aware object
+    */
+   private KeyConnectionAssociation peekMetaAwareObject()
+   {
+      LinkedList stack = currentObjects.get();
+
+      if (stack != null && !stack.isEmpty())
+      {
+         return stack.getLast();
+      }
+
+      return null;
+   }
+
+
+   /**
+    * {@inheritDoc}
+    */
+   @SuppressWarnings("unchecked")
+   public void popMetaAwareObject(Set unsharableResources) throws ResourceException
+   {
+      LinkedList stack = currentObjects.get();
+      KeyConnectionAssociation oldKey = stack.removeLast();
+
+      log.tracef("popped object: %s", oldKey);
+
+      if (Tracer.isEnabled())
+         Tracer.popCCMContext(oldKey.toString(), new Throwable("CALLSTACK"));
+
+      if (debug)
+      {
+         if (closeAll(oldKey) && error)
+         {
+            throw new ResourceException(bundle.someConnectionsWereNotClosed());
+         }
+      }
+   }
+
+   /**
+    * Register connection.
+    * @param cm connection manager
+    * @param cl connection listener
+    * @param connection connection handle
+    */
+   public void registerConnection(org.jboss.jca.core.api.connectionmanager.listener.ConnectionCacheListener cm,
+                                  org.jboss.jca.core.api.connectionmanager.listener.ConnectionListener cl,
+                                  Object connection)
+   {
+      if (debug)
+      {
+         synchronized (connectionStackTraces)
+         {
+            connectionStackTraces.put(connection, new Throwable("STACKTRACE"));
+         }
+      }
+
+      KeyConnectionAssociation key = peekMetaAwareObject();
+
+      log.tracef("registering connection from connection manager: %s, connection : %s, key: %s",
+                    cm, connection, key);
+
+      if (key != null)
+      {
+         if (Tracer.isEnabled())
+         {
+            ConnectionListener l = (ConnectionListener)cl;
+            Tracer.registerCCMConnection(l.getPool().getName(), l.getManagedConnectionPool(),
+                                         l, connection, key.toString());
+         }
+
+         ConnectionRecord cr = new ConnectionRecord(cl, connection);
+         ConcurrentMap> cmToConnectionsMap =
+            key.getCMToConnectionsMap();
+
+         CopyOnWriteArrayList conns = cmToConnectionsMap.get(cm);
+         if (conns == null)
+         {
+            conns = new CopyOnWriteArrayList();
+            cmToConnectionsMap.put((ConnectionCacheListener)cm, conns);
+         }
+
+         conns.add(cr);
+      }
+   }
+
+   /**
+    * Unregister connection.
+    * @param cm connection manager
+    * @param cl connection listener
+    * @param connection connection handle
+    */
+   public void unregisterConnection(org.jboss.jca.core.api.connectionmanager.listener.ConnectionCacheListener cm,
+                                    org.jboss.jca.core.api.connectionmanager.listener.ConnectionListener cl,
+                                    Object connection)
+   {
+      if (debug)
+      {
+         CloseConnectionSynchronization cas = getCloseConnectionSynchronization(false);
+         if (cas != null)
+         {
+            cas.remove(connection);
+         }
+
+         synchronized (connectionStackTraces)
+         {
+            connectionStackTraces.remove(connection);
+         }
+      }
+
+      KeyConnectionAssociation key = peekMetaAwareObject();
+
+      log.tracef("unregistering connection from connection manager: %s, connection: %s, key: %s",
+                    cm, connection, key);
+
+      if (key == null)
+         return;
+
+      ConcurrentMap> cmToConnectionsMap =
+         key.getCMToConnectionsMap();
+
+      CopyOnWriteArrayList conns = cmToConnectionsMap.get(cm);
+
+      // Can happen if connections are "passed" between contexts
+      if (conns == null)
+         return; 
+
+      // Note iterator of CopyOnWriteArrayList does not support remove method
+      // We use here remove on CopyOnWriteArrayList directly
+      for (ConnectionRecord connectionRecord : conns)
+      {
+         if (connectionRecord.getConnection() == connection)
+         {
+            if (Tracer.isEnabled())
+            {
+               ConnectionListener l = (ConnectionListener)cl;
+               Tracer.unregisterCCMConnection(l.getPool().getName(), l.getManagedConnectionPool(),
+                                              l, connection, key.toString());
+            }
+
+            conns.remove(connectionRecord);
+            return;
+         }
+      }
+
+      if (Tracer.isEnabled())
+      {
+         ConnectionListener l = (ConnectionListener)cl;
+         Tracer.unknownCCMConnection(l.getPool().getName(), l.getManagedConnectionPool(),
+                                     l, connection, key.toString());
+      }
+
+      if (!ignoreConnections)
+         throw new IllegalStateException(bundle.tryingToReturnUnknownConnection(connection.toString()));
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @SuppressWarnings("unchecked")
+   public void pushMetaAwareObject(final Object rawKey, Set unsharableResources) throws ResourceException
+   {
+      LinkedList stack = currentObjects.get();
+      KeyConnectionAssociation key = new KeyConnectionAssociation(rawKey);
+
+      if (stack == null)
+      {
+         log.tracef("new stack for key: %s", key);
+
+         stack = new LinkedList();
+         currentObjects.set(stack);
+      }
+      else if (stack.isEmpty())
+      {
+         log.tracef("new stack for key: %s", key);
+      }
+      else
+      {
+         log.tracef("old stack for key: %s", stack.getLast());
+         log.tracef("new stack for key: %s", key);
+      }
+
+      if (Tracer.isEnabled())
+         Tracer.pushCCMContext(key.toString(), new Throwable("CALLSTACK"));
+
+      stack.addLast(key);
+   }
+
+   /**
+    * Describe unregisterConnectionCacheListener method here.
+    * This is a shutdown method called by a connection manager.  It will remove all reference
+    * to that connection manager from the cache, so cached connections from that manager
+    * will never be recoverable.
+    * Possibly this method should not exist.
+    *
+    * @param cm a ConnectionCacheListener value
+    */
+   public void unregisterConnectionCacheListener(ConnectionCacheListener cm)
+   {
+      log.tracef("unregisterConnectionCacheListener: %s", cm);
+
+      Iterator>> it =
+         objectToConnectionManagerMap.values().iterator();
+
+      while (it.hasNext())
+      {
+         ConcurrentMap> cmToConnectionsMap = it.next();
+
+         if (cmToConnectionsMap != null)
+            cmToConnectionsMap.remove(cm);
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public int getNumberOfConnections()
+   {
+      if (!debug)
+         return 0;
+
+      synchronized (connectionStackTraces)
+      {
+         return connectionStackTraces.size();
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public Map listConnections()
+   {
+      if (!debug)
+         return Collections.unmodifiableMap(Collections.EMPTY_MAP);
+
+      synchronized (connectionStackTraces)
+      {
+         HashMap result = new HashMap();
+
+         for (Map.Entry entry : connectionStackTraces.entrySet())
+         {
+            Object key = entry.getKey();
+            Throwable stackTrace = entry.getValue();
+
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            PrintStream ps = new PrintStream(baos, true);
+            stackTrace.printStackTrace(ps);
+
+            result.put(key.toString(), baos.toString());
+         }
+
+         return Collections.unmodifiableMap(result);
+      }
+   }
+
+   /**
+    * Close all connections.
+    * @param key The key
+    * @return true if close
+    */
+   private boolean closeAll(KeyConnectionAssociation key)
+   {
+      ConcurrentMap> cmToConnectionsMap =
+         key.getCMToConnectionsMap();
+      boolean unclosed = false;
+
+      Collection> connections = cmToConnectionsMap.values();
+      if (connections.size() != 0)
+      {
+         for (Iterator> i = connections.iterator(); i.hasNext();)
+         {
+            CopyOnWriteArrayList conns = i.next();
+            for (ConnectionRecord cr : conns)
+            {
+               Object c = cr.getConnection();
+               CloseConnectionSynchronization cas = getCloseConnectionSynchronization(true);
+               if (cas == null)
+               {
+                  unclosed = true;
+
+                  if (Tracer.isEnabled())
+                  {
+                     ConnectionListener cl = (ConnectionListener)cr.getConnectionListener();
+                     Tracer.closeCCMConnection(cl.getPool().getName(), cl.getManagedConnectionPool(),
+                                               cl, c, key.toString());
+                  }
+
+                  closeConnection(c);
+               }
+               else
+               {
+                  cas.add(c);
+               }
+            }
+         }
+      }
+
+      return unclosed;
+   }
+
+   /**
+    * Gets close sync. instance.
+    * @param createIfNotFound create if not found
+    * @return sync. instance
+    */
+   private CloseConnectionSynchronization getCloseConnectionSynchronization(boolean createIfNotFound)
+   {
+      try
+      {
+         Transaction tx = null;
+         if (getTransactionManager() != null)
+         {
+            tx = getTransactionManager().getTransaction();
+         }
+
+         if (tx != null)
+         {
+            if (createIfNotFound)
+               TransactionSynchronizer.lock(tx, transactionIntegration);
+            try
+            {
+               CloseConnectionSynchronization cas = 
+                  (CloseConnectionSynchronization)TransactionSynchronizer.getCCMSynchronization(tx,
+                                                                                                transactionIntegration);
+
+               if (cas == null && createIfNotFound && TxUtils.isActive(tx))
+               {
+                  cas = new CloseConnectionSynchronization();
+                  TransactionSynchronizer.registerCCMSynchronization(tx, cas, transactionIntegration);
+               }
+
+               return cas;
+            }
+            finally
+            {
+               if (createIfNotFound)
+                  TransactionSynchronizer.unlock(tx, transactionIntegration);
+            }
+         }
+      }
+      catch (Throwable t)
+      {
+         log.debug("Unable to synchronize with transaction", t);
+      }
+
+      return null;
+   }
+
+
+   /**
+    * Close connection handle.
+    * @param connectionHandle connection handle
+    */
+   private void closeConnection(Object connectionHandle)
+   {
+      try
+      {
+         Throwable exception;
+
+         synchronized (connectionStackTraces)
+         {
+            exception = connectionStackTraces.remove(connectionHandle);
+         }
+
+         Method m = SecurityActions.getMethod(connectionHandle.getClass(), "close", new Class[]{});
+
+         try
+         {
+            if (exception != null)
+            {
+               log.closingConnection(connectionHandle, exception);
+            }
+            else
+            {
+               log.closingConnection(connectionHandle);
+            }
+
+            m.invoke(connectionHandle, new Object[]{});
+         }
+         catch (Throwable t)
+         {
+            log.closingConnectionThrowable(t);
+         }
+      }
+      catch (NoSuchMethodException nsme)
+      {
+         log.closingConnectionNoClose(connectionHandle.getClass().getName());
+      }
+   }
+
+
+   /**
+    * Close synch. class.
+    */
+   private class CloseConnectionSynchronization implements Synchronization
+   {
+      /**Connection handles*/
+      CopyOnWriteArraySet connections = new CopyOnWriteArraySet();
+
+      /**Closing flag*/
+      AtomicBoolean closing = new AtomicBoolean(false);
+
+      /**
+       * Creates a new instance.
+       */
+      public CloseConnectionSynchronization()
+      {
+      }
+
+      /**
+       * Add new connection handle.
+       * @param c connection handle
+       */
+      public  void add(Object c)
+      {
+         if (!closing.get())
+            connections.add(c);
+      }
+
+      /**
+       * Removes connection handle.
+       * @param c connection handle
+       */
+      public  void remove(Object c)
+      {
+         if (!closing.get())
+            connections.remove(c);
+      }
+
+      /**
+       * {@inheritDoc}
+       */
+      public void beforeCompletion()
+      {
+         // No-action
+      }
+
+      /**
+       * {@inheritDoc}
+       */
+      public void afterCompletion(int status)
+      {
+         closing.set(true);
+
+         for (Iterator i = connections.iterator(); i.hasNext();)
+         {
+            closeConnection(i.next());
+         }
+
+         connections.clear();
+      }
+   }
+
+   /**
+    * Get the currentObjects.
+    * This method is package protected beacause it is intended only for test case use.
+    * Please don't use it in your production code.
+    *
+    * @return the currentObjects.
+    */
+   final ThreadLocal> getCurrentObjects()
+   {
+      return currentObjects;
+   }
+
+   /**
+    * String representation
+    * @return The string
+    */
+   @Override
+   public String toString()
+   {
+      StringBuilder sb = new StringBuilder();
+
+      sb.append("CachedConnectionManagerImpl@").append(Integer.toHexString(System.identityHashCode(this)));
+      sb.append("[debug=").append(debug);
+      sb.append(" error=").append(error);
+      sb.append(" ignoreConnections=").append(ignoreConnections);
+      sb.append(" transactionIntegration=").append(transactionIntegration);
+      sb.append(" currentObjects=").append(currentObjects.get());
+      sb.append(" objectToConnectionManagerMap=").append(objectToConnectionManagerMap);
+      sb.append(" connectionStackTraces=").append(connectionStackTraces);
+      sb.append("]");
+
+      return sb.toString();
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ccm/KeyConnectionAssociation.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ccm/KeyConnectionAssociation.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ccm/KeyConnectionAssociation.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,108 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2008-2009, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager.ccm;
+
+import org.jboss.jca.core.connectionmanager.ConnectionRecord;
+import org.jboss.jca.core.connectionmanager.listener.ConnectionCacheListener;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * The class KeyConnectionAssociation wraps objects so they may be used in hashmaps
+ * based on their object identity rather than equals implementation. Used for keys.
+ * 
+ * @author Gurkan Erdogdu 
+ * @version $Rev$
+ */
+final class KeyConnectionAssociation
+{
+   //key
+   private final Object metaAwareObject;
+
+   //map of cm to list of connections for that cm.
+   private ConcurrentMap> cmToConnectionsMap;
+
+   /**
+    * Creates a new instance.
+    * @param metaAwareObject meta aware object
+    */
+   KeyConnectionAssociation(final Object metaAwareObject)
+   {
+      this.metaAwareObject = metaAwareObject;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean equals(Object other)
+   {
+      if (other == this)
+         return true;
+
+      if (other == null || !(other instanceof KeyConnectionAssociation))
+         return false;
+
+      KeyConnectionAssociation kca = (KeyConnectionAssociation)other;
+
+      return metaAwareObject.equals(kca.metaAwareObject);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public String toString()
+   {
+      return metaAwareObject.getClass().getName() + '@' + Integer.toHexString(System.identityHashCode(metaAwareObject));
+   }
+   
+   /**
+    * {@inheritDoc}
+    */
+   public int hashCode()
+   {
+      return System.identityHashCode(metaAwareObject);
+   }
+
+   /**
+    * Set map instance.
+    * @param cmToConnectionsMap connection manager to connections
+    */
+   public void setCMToConnectionsMap(ConcurrentMap> cmToConnectionsMap)
+   {
+      this.cmToConnectionsMap = cmToConnectionsMap;
+   }
+
+   /**
+    * 
+    * @return map instance
+    */
+   public ConcurrentMap> getCMToConnectionsMap()
+   {
+      if (cmToConnectionsMap == null)
+         cmToConnectionsMap = new ConcurrentHashMap>();
+      
+      return cmToConnectionsMap;
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ccm/SecurityActions.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ccm/SecurityActions.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ccm/SecurityActions.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,76 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2008-2009, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager.ccm;
+
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Privileged Blocks
+ * @author Jesper Pedersen 
+ */
+class SecurityActions
+{ 
+   /**
+    * Constructor
+    */
+   private SecurityActions()
+   {
+   }
+
+   /**
+    * Get the method
+    * @param c The class
+    * @param name The name
+    * @param params The parameters
+    * @return The method
+    * @exception NoSuchMethodException If a matching method is not found.
+    */
+   static Method getMethod(final Class> c, final String name, final Class>... params)
+      throws NoSuchMethodException
+   {
+      if (System.getSecurityManager() == null)
+         return c.getMethod(name, params);
+
+      Method result = AccessController.doPrivileged(new PrivilegedAction()
+      {
+         public Method run()
+         {
+            try
+            {
+               return c.getMethod(name, params);
+            }
+            catch (NoSuchMethodException e)
+            {
+               return null;
+            }
+         }
+      });
+
+      if (result != null)
+         return result;
+
+      throw new NoSuchMethodException();
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ccm/package.html
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ccm/package.html	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/ccm/package.html	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,3 @@
+
+This package contains the cached connection manager.
+
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/AbstractConnectionListener.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/AbstractConnectionListener.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/AbstractConnectionListener.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,736 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2008-2009, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager.listener;
+
+import org.jboss.jca.common.api.metadata.common.FlushStrategy;
+import org.jboss.jca.core.CoreBundle;
+import org.jboss.jca.core.CoreLogger;
+import org.jboss.jca.core.api.connectionmanager.ccm.CachedConnectionManager;
+import org.jboss.jca.core.api.connectionmanager.pool.FlushMode;
+import org.jboss.jca.core.connectionmanager.ConnectionManager;
+import org.jboss.jca.core.connectionmanager.pool.api.Pool;
+import org.jboss.jca.core.connectionmanager.pool.mcp.ManagedConnectionPool;
+import org.jboss.jca.core.spi.transaction.ConnectableResourceListener;
+import org.jboss.jca.core.tracer.Tracer;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.ConnectionEvent;
+import javax.resource.spi.ManagedConnection;
+import javax.transaction.SystemException;
+
+import org.jboss.logging.Messages;
+
+/**
+ * Abstract implementation of the {@link ConnectionListener} interface
+ * contract.
+ * 
+ * @author Gurkan Erdogdu  
+ * @author Jesper Pedersen  
+ */
+public abstract class AbstractConnectionListener implements ConnectionListener, ConnectableResourceListener
+{
+   private final CoreLogger log;
+
+   /** The bundle */
+   private static CoreBundle bundle = Messages.getBundle(CoreBundle.class);
+   
+   /** Connection Manager */
+   private final ConnectionManager cm;
+      
+   /** Managed connection */
+   private final ManagedConnection managedConnection;
+   
+   /** Pool for this connection */
+   private final Pool pool;
+   
+   /** Managed connection pool */
+   private final ManagedConnectionPool managedConnectionPool;
+
+   /** Flush strategy */
+   private FlushStrategy flushStrategy;
+   
+   /** Connection State */
+   private ConnectionState state = ConnectionState.NORMAL;
+   
+   /** Connection handles */
+   protected CopyOnWriteArraySet connectionHandles = new CopyOnWriteArraySet();
+
+   /** Connection traces */
+   protected Map connectionTraces;
+      
+   /** Track by transaction or not */
+   private final AtomicBoolean trackByTx = new AtomicBoolean(false);
+   
+   /** Connection last returned */
+   private long lastReturned;
+   
+   /** Connection last validated time */
+   private long lastValidated;
+
+   /** Connection check out time */
+   private long lastCheckedOut;
+
+   /** Enlisted */
+   private boolean enlisted;
+
+   /** Tracking */
+   protected Boolean tracking;
+
+   /** The reported exception */
+   private Exception reportedException;
+   
+   /**
+    * Creates a new instance of the listener that is responsible for
+    * tracking the owned connection instance.
+    * @param cm connection manager
+    * @param managedConnection managed connection
+    * @param pool pool
+    * @param mcp managed connection pool
+    * @param flushStrategy flushStrategy
+    * @param tracking tracking
+    */
+   protected AbstractConnectionListener(ConnectionManager cm, ManagedConnection managedConnection, 
+                                        Pool pool, ManagedConnectionPool mcp, FlushStrategy flushStrategy,
+                                        Boolean tracking)
+   {
+      this.cm = cm;
+      this.managedConnection = managedConnection;
+      this.pool = pool;
+      this.managedConnectionPool = mcp;
+      this.flushStrategy = flushStrategy;
+      this.log = getLogger();
+      this.enlisted = false;
+
+      long createdTime = System.currentTimeMillis();
+      this.lastReturned = createdTime;
+      this.lastValidated = createdTime;
+      this.lastCheckedOut = createdTime;
+
+      this.tracking = tracking;
+
+      if (tracking != null && tracking.booleanValue())
+         this.connectionTraces = new HashMap();
+
+      this.reportedException = null;
+   }
+
+   /**
+    * Gets cached connection manager
+    * @return cached connection manager
+    */
+   protected CachedConnectionManager getCachedConnectionManager()
+   {
+      return cm.getCachedConnectionManager();
+   }
+   
+   /**
+    * Gets connection manager.
+    * @return connection manager
+    */
+   protected ConnectionManager getConnectionManager()
+   {
+      return cm;
+   }
+   
+   /**
+    * Get the logger
+    * @return The value
+    */
+   protected abstract CoreLogger getLogger();
+   
+   /**
+    * {@inheritDoc}
+    */
+   public int getNumberOfConnections()
+   {
+      return connectionHandles.size();
+   }
+
+   /**
+    * {@inheritDoc}
+    */   
+   public boolean isEnlisted()
+   {
+      return enlisted;
+   }
+
+   /**
+    * Set the enlisted flag
+    * @param v The value
+    */   
+   void setEnlisted(boolean v)
+   {
+      enlisted = v;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean delist() throws ResourceException
+   {
+      return true;
+   }
+
+   /**
+    * {@inheritDoc}
+    */   
+   public void enlist() throws SystemException
+   {
+   }
+
+   /**
+    * {@inheritDoc}
+    */   
+   public ManagedConnectionPool getManagedConnectionPool()
+   {
+      return managedConnectionPool;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getLastValidatedTime()
+   {      
+      return lastValidated;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getLastReturnedTime()
+   {
+      return lastReturned;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getLastCheckedOutTime()
+   {
+      return lastCheckedOut;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void setLastCheckedOutTime(long v)
+   {
+      lastCheckedOut = v;
+   }
+
+   /**
+    * {@inheritDoc}
+    */   
+   public ManagedConnection getManagedConnection()
+   {      
+      return managedConnection;
+   }
+
+   /**
+    * {@inheritDoc}
+    */   
+   public Pool getPool()
+   {      
+      return pool;
+   }
+
+   /**
+    * {@inheritDoc}
+    */   
+   public ConnectionState getState()
+   {      
+      return state;
+   }
+
+   /**
+    * {@inheritDoc}
+    */   
+   public boolean isManagedConnectionFree()
+   {
+      if (log.isTraceEnabled())
+         log.tracef("[%s] isManagedConnectionFree: %s", getIdentifier(), connectionHandles.isEmpty());
+
+      return connectionHandles.isEmpty();
+   }
+
+   /**
+    * {@inheritDoc}
+    */   
+   public boolean isTimedOut(long timeout)
+   {      
+      return lastReturned < timeout;
+   }
+
+   /**
+    * {@inheritDoc}
+    */   
+   public boolean isTrackByTx()
+   {      
+      return trackByTx.get();
+   }
+
+   /**
+    * {@inheritDoc}
+    */   
+   public void registerConnection(Object handle)
+   {
+      if (handle != null)
+      {
+         connectionHandles.add(handle);
+
+         if (Tracer.isEnabled())
+            Tracer.getConnection(pool != null ? pool.getName() : null, managedConnectionPool, this, handle);
+
+         if (log.isTraceEnabled())
+            log.tracef("[%s] registerConnection: %s [size=%s] (%s)", getIdentifier(), handle,
+                       connectionHandles.size(), connectionHandles);
+
+         if (tracking != null && tracking.booleanValue())
+            connectionTraces.put(handle, new Exception());
+      }
+      else
+      {
+         log.registeredNullHandleManagedConnection(managedConnection);
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */   
+   public void setLastValidatedTime(long lastValidated)
+   {
+      this.lastValidated = lastValidated;      
+   }
+
+   /**
+    * {@inheritDoc}
+    */   
+   public void setState(ConnectionState newState)
+   {
+      this.state = newState;      
+   }
+
+   /**
+    * {@inheritDoc}
+    */   
+   public void setTrackByTx(boolean trackByTx)
+   {      
+      this.trackByTx.set(trackByTx);
+   }
+
+   /**
+    * {@inheritDoc}
+    */   
+   public void tidyup() throws ResourceException
+   {
+   }
+
+   /**
+    * {@inheritDoc}
+    */   
+   public void unregisterConnection(Object handle)
+   {
+      if (handle != null)
+      {
+         if (!connectionHandles.remove(handle))
+         {
+            log.unregisteredHandleNotRegistered(handle, managedConnection);
+         }
+
+         if (Tracer.isEnabled())
+            Tracer.returnConnection(pool != null ? pool.getName() : null, managedConnectionPool, this, handle);
+
+         if (tracking != null && tracking.booleanValue())
+            connectionTraces.remove(handle);
+      }
+      else
+      {
+         log.unregisteredNullHandleManagedConnection(managedConnection);
+      }
+      
+      if (log.isTraceEnabled())
+         log.tracef("[%s] unregisterConnection: " + connectionHandles.size() + " handles left (%s)",
+                    getIdentifier(), connectionHandles);
+   }
+   
+   /**
+    * Unregister connections.
+    */
+   public  void unregisterConnections()
+   {
+      if (log.isTraceEnabled())
+         log.tracef("[%s] unregisterConnections", getIdentifier());
+
+      if (getCachedConnectionManager() != null)
+      {
+         for (Object handle : connectionHandles)
+         {
+            getCachedConnectionManager().unregisterConnection(getConnectionManager(), this, handle);
+         }
+      }
+
+      if (Tracer.isEnabled())
+      {
+         for (Object handle : connectionHandles)
+         {
+            Tracer.returnConnection(pool != null ? pool.getName() : null, managedConnectionPool, this, handle);
+         }
+      }
+
+      connectionHandles.clear();
+
+      if (tracking != null && tracking.booleanValue())
+         connectionTraces.clear();
+   }
+   
+
+   /**
+    * {@inheritDoc}
+    */   
+   public void toPool()
+   {
+      lastReturned = System.currentTimeMillis();
+   }
+
+   /**
+    * {@inheritDoc}
+    */   
+   public void connectionClosed(ConnectionEvent event)
+   {
+   }
+
+   /**
+    * {@inheritDoc}
+    */   
+   public void connectionErrorOccurred(ConnectionEvent event)
+   {
+      if (state == ConnectionState.NORMAL)
+      {
+         if (event != null)
+         {
+            Exception cause = event.getException();
+            if (cause == null)
+            {
+               cause = new Exception("No exception was reported");  
+            }
+            else
+            {
+               reportedException = cause;
+            }
+            
+            log.connectionErrorOccured(this, cause);
+         }
+         else
+         {
+            Exception cause = new Exception("No exception was reported");
+            log.unknownConnectionErrorOccured(this, cause);
+         }
+      }
+      
+      try
+      {
+         unregisterConnections();
+      }
+      catch (Throwable t)
+      {
+         //ignore, it wasn't checked out.
+      }
+      
+      if (event != null && event.getSource() != getManagedConnection())
+      {
+         log.notifiedErrorDifferentManagedConnection();
+      }
+
+      haltCatchFire();
+      
+      getConnectionManager().returnManagedConnection(this, true);      
+
+      if (flushStrategy == FlushStrategy.FAILING_CONNECTION_ONLY)
+      {
+         managedConnectionPool.prefill();
+      }
+      else if (flushStrategy == FlushStrategy.INVALID_IDLE_CONNECTIONS)
+      {
+         Collection toDestroy = new ArrayList();
+         managedConnectionPool.flush(FlushMode.INVALID, toDestroy);
+         for (ConnectionListener connectionListener: toDestroy)
+         {
+            connectionListener.destroy();
+         }
+      }
+      else if (flushStrategy == FlushStrategy.IDLE_CONNECTIONS)
+      {
+         Collection toDestroy = new ArrayList();
+         managedConnectionPool.flush(FlushMode.IDLE, toDestroy);
+         for (ConnectionListener connectionListener: toDestroy)
+         {
+            connectionListener.destroy();
+         }
+      }
+      else if (flushStrategy == FlushStrategy.GRACEFULLY)
+      {
+         Collection toDestroy = new ArrayList();
+         managedConnectionPool.flush(FlushMode.GRACEFULLY, toDestroy);
+         for (ConnectionListener connectionListener: toDestroy)
+         {
+            connectionListener.destroy();
+         }
+      }
+      else if (flushStrategy == FlushStrategy.ENTIRE_POOL)
+      {
+         Collection toDestroy = new ArrayList();
+         managedConnectionPool.flush(FlushMode.ALL, toDestroy);
+         for (ConnectionListener connectionListener: toDestroy)
+         {
+            connectionListener.destroy();
+         }
+      }
+      else if (flushStrategy == FlushStrategy.ALL_INVALID_IDLE_CONNECTIONS)
+      {
+         pool.flush(FlushMode.INVALID);
+      }
+      else if (flushStrategy == FlushStrategy.ALL_IDLE_CONNECTIONS)
+      {
+         pool.flush(FlushMode.IDLE);
+      }
+      else if (flushStrategy == FlushStrategy.ALL_GRACEFULLY)
+      {
+         pool.flush(FlushMode.GRACEFULLY);
+      }
+      else if (flushStrategy == FlushStrategy.ALL_CONNECTIONS)
+      {
+         pool.flush(FlushMode.ALL);
+      }
+   }
+   
+   /**
+    * {@inheritDoc}
+    */
+   public Exception getException()
+   {
+      return reportedException;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean controls(ManagedConnection mc, Object connection)
+   {
+      if (managedConnection.equals(mc))
+      {
+         if (connection == null || connectionHandles.contains(connection))
+            return true;
+      }
+
+      return false;
+   }
+   
+   /**
+    * {@inheritDoc}
+    */
+   public void dissociate() throws ResourceException
+   {
+      // Nothing by default
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean supportsLazyAssociation()
+   {
+      return managedConnection instanceof javax.resource.spi.DissociatableManagedConnection;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean supportsLazyEnlistment()
+   {
+      return managedConnection instanceof javax.resource.spi.LazyEnlistableManagedConnection;
+   }
+
+   /**
+    * {@inheritDoc}
+    */   
+   public void localTransactionCommitted(ConnectionEvent event)
+   {
+   }
+
+   /**
+    * {@inheritDoc}
+    */   
+   public void localTransactionRolledback(ConnectionEvent event)
+   {
+   }
+
+   /**
+    * {@inheritDoc}
+    */   
+   public void localTransactionStarted(ConnectionEvent event)
+   {
+   }
+
+   /**
+    * {@inheritDoc}
+    */   
+   public void handleCreated(Object h)
+   {
+      registerConnection(h);
+
+      if (getCachedConnectionManager() != null)
+      {
+         getCachedConnectionManager().registerConnection(getConnectionManager(), this, h);
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */   
+   public void handleClosed(Object h)
+   {
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void destroy()
+   {
+      if (getState() == ConnectionState.DESTROYED)
+      {
+         log.tracef("ManagedConnection is already destroyed %s", this);
+         return;
+      }
+
+      getManagedConnectionPool().connectionListenerDestroyed(this);
+
+      setState(ConnectionState.DESTROYED);
+
+      final ManagedConnection mc = getManagedConnection();
+      try
+      {
+         mc.destroy();
+      }
+      catch (Throwable t)
+      {
+         if (log.isDebugEnabled())
+            log.debug("Exception destroying ManagedConnection " + this, t);
+      }
+
+      mc.removeConnectionEventListener(this);
+   }
+
+   /**
+    * Halt and Catch Fire
+    */
+   void haltCatchFire()
+   {
+      // Do nothing by default
+   }
+   
+   /**
+    * Compare
+    * @param o The other object
+    * @return 0 if equal; -1 if less than based on lastReturned; otherwise 1
+    */
+   public int compareTo(Object o)
+   {
+      if (this == o)
+         return 0;
+
+      if (!(o instanceof AbstractConnectionListener))
+         throw new ClassCastException(bundle.notCorrectTypeWhenClassCast(o.getClass().getName()));
+
+      final AbstractConnectionListener acl = (AbstractConnectionListener)o;
+
+      if (lastReturned < acl.lastReturned)
+         return -1;
+
+      return 1;
+   }
+
+   /**
+    * Get string identifier
+    * @return The value
+    */
+   private String getIdentifier()
+   {
+      StringBuffer buffer = new StringBuffer(100);
+      buffer.append(getClass().getSimpleName()).append('@').append(Integer.toHexString(System.identityHashCode(this)));
+      return buffer.toString();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public String toString()
+   {
+      StringBuffer buffer = new StringBuffer(100);
+      buffer.append(getClass().getName()).append('@').append(Integer.toHexString(System.identityHashCode(this)));
+      buffer.append("[state=");
+      
+      if (state.equals(ConnectionState.NORMAL))
+      {
+         buffer.append("NORMAL");  
+      }
+      else if (state.equals(ConnectionState.DESTROY))
+      {
+         buffer.append("DESTROY");  
+      }
+      else if (state.equals(ConnectionState.DESTROYED))
+      {
+         buffer.append("DESTROYED");  
+      }
+      else
+      {
+         buffer.append("UNKNOWN?");  
+      }
+      buffer.append(" managed connection=").append(managedConnection);
+      buffer.append(" connection handles=").append(connectionHandles.size());
+      buffer.append(" lastReturned=").append(lastReturned);
+      buffer.append(" lastValidated=").append(lastValidated);
+      buffer.append(" lastCheckedOut=").append(lastCheckedOut);
+      buffer.append(" trackByTx=").append(trackByTx.get());
+      buffer.append(" pool=").append(pool);
+      buffer.append(" mcp=").append(managedConnectionPool);
+      toString(buffer);
+      buffer.append(']');
+      
+      return buffer.toString();
+   }
+   
+   /**
+    * Add specific properties.
+    * @param buffer buffer instance
+    */
+   protected void toString(StringBuffer buffer)
+   {
+      
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/ConnectionCacheListener.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/ConnectionCacheListener.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/ConnectionCacheListener.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,49 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2006, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager.listener;
+
+import org.jboss.jca.core.connectionmanager.ConnectionRecord;
+
+import java.util.Collection;
+
+import javax.transaction.SystemException;
+
+
+/**
+ * ConnectionCacheListener.
+ *
+ * @author David Jencks 
+ * @author Erwin Guib 
+ * @author Adrian Brock 
+ * @author Jesper Pedersen 
+ */
+public interface ConnectionCacheListener
+   extends org.jboss.jca.core.api.connectionmanager.listener.ConnectionCacheListener
+{
+   /**
+    * Notification of transaction started
+    * 
+    * @param conns the connections
+    * @throws SystemException for any error
+    */
+   void transactionStarted(Collection conns) throws SystemException;
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/ConnectionListener.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/ConnectionListener.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/ConnectionListener.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,229 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2006, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager.listener;
+
+import org.jboss.jca.core.connectionmanager.pool.api.Pool;
+import org.jboss.jca.core.connectionmanager.pool.mcp.ManagedConnectionPool;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.ManagedConnection;
+import javax.transaction.SystemException;
+
+/**
+ * Connection listener.
+ * 
+ * @author Gurkan Erdogdu 
+ * @author Adrian Brock 
+ * @author Weston Price 
+ * @author Jesper Pedersen 
+ */
+public interface ConnectionListener extends org.jboss.jca.core.api.connectionmanager.listener.ConnectionListener
+{
+   /**
+    * Get number of connection handles
+    * @return The value
+    */
+   public int getNumberOfConnections();
+
+   /**
+    * Retrieve the pool for this listener.
+    * 
+    * @return the pool
+    */
+   public Pool getPool();
+
+   /**
+    * Tidyup
+    * 
+    * Invoked just before returning the connection to the pool when the
+    * connection is not being destroyed.
+    * 
+    * @throws ResourceException for any error
+    */
+   public void tidyup() throws ResourceException;
+
+   /**
+    * Get the managed connection pool
+    * @return The value
+    */
+   public ManagedConnectionPool getManagedConnectionPool();
+
+   /**
+    * Retrieve the state of this connection.
+    * 
+    * @return the state
+    */
+   public ConnectionState getState();
+
+   /**
+    * Set the state of this connection.
+    * 
+    * @param newState new state
+    */
+   public void setState(ConnectionState newState);
+
+   /**
+    * Has the connection timed out?
+    * 
+    * @param timeout the timeout
+    * @return true for timed out, false otherwise
+    */
+   public boolean isTimedOut(long timeout);
+
+   /**
+    * Mark the connection as in pool
+    */
+   public void toPool();
+
+   /**
+    * Register a new connection
+    * 
+    * @param handle the connection handle
+    */
+   public void registerConnection(Object handle);
+
+   /**
+    * Unregister a connection
+    * 
+    * @param handle the connection handle
+    */
+   public void unregisterConnection(Object handle);
+
+   /**
+    * Unregister all connections
+    */
+   public void unregisterConnections();
+
+   /**
+    * Is the managed connection free?
+    * 
+    * @return true when it is free
+    */
+   public boolean isManagedConnectionFree();
+
+   /**
+    * Is enlisted
+    * @return True if enlisted, otherwise false
+    */
+   public boolean isEnlisted();
+
+   /**
+    * Enlist the managed connection
+    * 
+    * @throws SystemException for errors
+    */
+   public void enlist() throws SystemException;
+
+   /**
+    * Delist the managed connection
+    * @return True if the listener was delisted succesfully, otherwise false
+    * @throws ResourceException if exception occurs
+    */
+   public boolean delist() throws ResourceException;
+
+   /**
+    * Get whether the listener is track by transaction
+    * 
+    * @return true for track by transaction, false otherwise
+    */
+   public boolean isTrackByTx();
+
+   /**
+    * Set whether the listener is track by transaction
+    * 
+    * @param trackByTx true for track by transaction, false otherwise
+    */
+   public void setTrackByTx(boolean trackByTx);
+
+   /**
+    * Retrieve the last time this connection was validated.
+    * 
+    * @return the last time the connection was validated
+    */
+   public long getLastValidatedTime();
+
+   /**
+    * Set the last time, in milliseconds, that this connection was validated.
+    * 
+    * @param lastValidated the last time the connection was validated in
+    *           milliseconds.
+    */
+   public void setLastValidatedTime(long lastValidated);
+
+   /**
+    * Retrieve the last time this connection was returned to the pool
+    * 
+    * @return the last time the connection was returned to the pool
+    */
+   public long getLastReturnedTime();
+
+   /**
+    * Retrieve the last time this connection was obtained from the pool
+    * 
+    * @return the last time the connection was obtained from the pool
+    */
+   public long getLastCheckedOutTime();
+
+   /**
+    * Set the last time this connection was obtained from the pool
+    *
+    * @param v The value
+    */
+   public void setLastCheckedOutTime(long v);
+
+   /**
+    * Get exception
+    * @return The exception that occured, or null
+    */
+   public Exception getException();
+
+   /**
+    * Controls the managed connection / connection pair
+    * @param mc The managed connection
+    * @param connection The connection; optional
+    * @return True if the connection listener controls the pair, otherwise false
+    */
+   public boolean controls(ManagedConnection mc, Object connection);
+
+   /**
+    * Dissociate the connection listener
+    * @throws ResourceException if exception occurs
+    */
+   public void dissociate() throws ResourceException;
+
+   /**
+    * Supports lazy association
+    * @return True if supported, otherwise false
+    */
+   public boolean supportsLazyAssociation();
+
+   /**
+    * Supports lazy enlistment
+    * @return True if supported, otherwise false
+    */
+   public boolean supportsLazyEnlistment();
+
+   /**
+    * Destroys this connection listener and its managed connection.
+    */
+   public void destroy();
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/ConnectionState.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/ConnectionState.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/ConnectionState.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,47 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2008-2009, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager.listener;
+
+/**
+ * Connection listener status flag. Connections can be in three state
+ * 
+ *    NORMAL 
+ *    DESTROY 
+ *    DESTROYED 
+ *  
+ * 
+ * @version $Rev: $
+ * @author Gurkan Erdogdu 
+ */
+public enum ConnectionState
+{
+   /**Normal state*/
+   NORMAL,
+   
+   /**Destroy this connection*/
+   DESTROY,
+   
+   /**Connection is destroyed*/
+   DESTROYED;
+
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/NoTxConnectionListener.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/NoTxConnectionListener.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/NoTxConnectionListener.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,96 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2008-2009, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager.listener;
+
+import org.jboss.jca.common.api.metadata.common.FlushStrategy;
+import org.jboss.jca.core.CoreLogger;
+import org.jboss.jca.core.connectionmanager.ConnectionManager;
+import org.jboss.jca.core.connectionmanager.pool.api.Pool;
+import org.jboss.jca.core.connectionmanager.pool.mcp.ManagedConnectionPool;
+
+import javax.resource.spi.ConnectionEvent;
+import javax.resource.spi.ManagedConnection;
+
+import org.jboss.logging.Logger;
+
+/**
+ * NoTx Connection Listener.
+ * 
+ * @author Gurkan Erdogdu  
+ * @author Jesper Pedersen  
+ * @see AbstractConnectionListener
+ */
+public class NoTxConnectionListener extends AbstractConnectionListener
+{
+   /** The logger */
+   private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, 
+      NoTxConnectionListener.class.getName());
+
+   /**
+    * Creates a new no-tx listener.
+    * @param cm connection manager
+    * @param mc managed connection
+    * @param pool pool
+    * @param mcp mcp
+    * @param flushStrategy flushStrategy
+    * @param tracking tracking
+    */
+   public NoTxConnectionListener(final ConnectionManager cm, final ManagedConnection mc, 
+                                 final Pool pool, final ManagedConnectionPool mcp, final FlushStrategy flushStrategy,
+                                 final Boolean tracking)
+   {
+      super(cm, mc, pool, mcp, flushStrategy, tracking);
+   }
+   
+   /**
+    * {@inheritDoc}
+    */
+   protected CoreLogger getLogger()
+   {
+      return log;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void connectionClosed(ConnectionEvent ce)
+   {
+      if (getCachedConnectionManager() != null)
+      {
+         try
+         {
+            getCachedConnectionManager().unregisterConnection(getConnectionManager(), this, ce.getConnectionHandle());
+         }
+         catch (Throwable t)
+         {
+            log.debug("Throwable from unregisterConnection", t);
+         }
+      }
+
+      getConnectionManager().unregisterAssociation(this, ce.getConnectionHandle());
+      
+      if (isManagedConnectionFree())
+      {
+         getConnectionManager().returnManagedConnection(this, false);
+      }
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/SecurityActions.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/SecurityActions.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/SecurityActions.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,50 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2013, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors. 
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager.listener;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Privileged Blocks
+ * 
+ * @author Jesper Pedersen 
+ */
+class SecurityActions
+{
+   /**
+    * Get a system property
+    * @param name The property name
+    * @return The property value
+    */
+   static String getSystemProperty(final String name)
+   {
+      return AccessController.doPrivileged(new PrivilegedAction() 
+      {
+         public String run()
+         {
+            return System.getProperty(name);
+         }
+      });
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/TxConnectionListener.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/TxConnectionListener.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/TxConnectionListener.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,1247 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2008-2009, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager.listener;
+
+import org.jboss.jca.common.api.metadata.common.FlushStrategy;
+import org.jboss.jca.core.CoreBundle;
+import org.jboss.jca.core.CoreLogger;
+import org.jboss.jca.core.connectionmanager.ConnectionManager;
+import org.jboss.jca.core.connectionmanager.TxConnectionManager;
+import org.jboss.jca.core.connectionmanager.pool.api.Pool;
+import org.jboss.jca.core.connectionmanager.pool.mcp.ManagedConnectionPool;
+import org.jboss.jca.core.connectionmanager.transaction.LockKey;
+import org.jboss.jca.core.connectionmanager.transaction.TransactionSynchronizer;
+import org.jboss.jca.core.connectionmanager.tx.TxConnectionManagerImpl;
+import org.jboss.jca.core.spi.transaction.ConnectableResource;
+import org.jboss.jca.core.spi.transaction.TxUtils;
+import org.jboss.jca.core.spi.transaction.local.LocalXAResource;
+import org.jboss.jca.core.tracer.Tracer;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.locks.Lock;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.ConnectionEvent;
+import javax.resource.spi.LocalTransaction;
+import javax.resource.spi.ManagedConnection;
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import javax.transaction.TransactionSynchronizationRegistry;
+import javax.transaction.xa.XAException;
+import javax.transaction.xa.XAResource;
+
+import org.jboss.logging.Logger;
+import org.jboss.logging.Messages;
+
+/**
+ * Tx connection listener.
+ * @author Gurkan Erdogdu 
+ * @author Jesper Pedersen 
+ */
+public class TxConnectionListener extends AbstractConnectionListener
+{
+   /** The logger */
+   private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, 
+      TxConnectionListener.class.getName());
+   
+   /** The bundle */
+   private static CoreBundle bundle = Messages.getBundle(CoreBundle.class);
+   
+   /** Disable failed to enlist message */
+   private static boolean disableFailedtoEnlist = false;
+
+   /**Transaction synch. instance*/
+   private TransactionSynchronization transactionSynchronization;
+
+   /**XAResource instance*/
+   private final XAResource xaResource;
+
+   /** XAResource timeout */
+   private final int xaResourceTimeout;
+
+   /** Whether there is a local transaction */
+   private final AtomicBoolean localTransaction = new AtomicBoolean(false);
+
+   /** Delist resource */
+   private boolean doDelistResource;
+
+   /** Set rollback */
+   private boolean doSetRollbackOnly;
+
+   /** Enlistment trace */
+   private Boolean enlistmentTrace;
+
+   static
+   {
+      String value = SecurityActions.getSystemProperty("ironjacamar.disable_enlistment_trace");
+
+      if (value != null && !value.trim().equals(""))
+      {
+         try
+         {
+            disableFailedtoEnlist = Boolean.valueOf(value);
+         }
+         catch (Throwable t)
+         {
+            // Assume enable
+            disableFailedtoEnlist = true;
+         }
+      }
+   }
+
+   /**
+    * Creates a new tx listener.
+    * @param cm connection manager
+    * @param mc managed connection
+    * @param pool pool
+    * @param mcp mcp
+    * @param flushStrategy flushStrategy
+    * @param tracking tracking
+    * @param enlistmentTrace enlistmentTrace
+    * @param xaResource xaresource instance
+    * @param xaResourceTimeout timeout for the XAResource
+    * @throws ResourceException if aexception while creating
+    */
+   public TxConnectionListener(final ConnectionManager cm, final ManagedConnection mc,
+                               final Pool pool, final ManagedConnectionPool mcp, final FlushStrategy flushStrategy,
+                               final Boolean tracking, final Boolean enlistmentTrace,
+                               final XAResource xaResource, final int xaResourceTimeout)
+      throws ResourceException
+   {
+      super(cm, mc, pool, mcp, flushStrategy, tracking);
+
+      this.xaResource = xaResource;
+      this.xaResourceTimeout = xaResourceTimeout;
+      this.doDelistResource = true;
+      this.doSetRollbackOnly = true;
+      this.enlistmentTrace = enlistmentTrace;
+      
+      if (xaResource instanceof LocalXAResource)
+      {
+         ((LocalXAResource) xaResource).setConnectionListener(this);
+      }
+      if (xaResource instanceof ConnectableResource)
+      {
+         ((ConnectableResource) xaResource).setConnectableResourceListener(this);
+      }
+
+      String value = SecurityActions.getSystemProperty("ironjacamar.no_delist_resource");
+      if (value != null && !value.trim().equals(""))
+      {
+         StringTokenizer st = new StringTokenizer(value, ",");
+         while (doDelistResource && st.hasMoreTokens())
+         {
+            if (getPool().getName().equals(st.nextToken()))
+               doDelistResource = false;
+         }
+      }
+      value = SecurityActions.getSystemProperty("ironjacamar.no_delist_resource_all");
+      if (value != null && !value.trim().equals(""))
+      {
+         doDelistResource = false;
+      }
+
+      value = SecurityActions.getSystemProperty("ironjacamar.rollback_on_fatal_error");
+      if (value != null && !value.trim().equals(""))
+      {
+         if ("true".equalsIgnoreCase(value) || "false".equalsIgnoreCase(value))
+         {
+            doSetRollbackOnly = Boolean.parseBoolean(value);
+         }
+         else
+         {
+            StringTokenizer st = new StringTokenizer(value, ",");
+            while (doSetRollbackOnly && st.hasMoreTokens())
+            {
+               if (getPool().getName().equals(st.nextToken()))
+                  doSetRollbackOnly = false;
+            }
+         }
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   protected CoreLogger getLogger()
+   {
+      return log;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public void toPool()
+   {
+      super.toPool();
+
+      // Do a reset of the underlying XAResource timeout
+      if (!(xaResource instanceof LocalXAResource) && xaResourceTimeout > 0)
+      {
+         try
+         {
+            xaResource.setTransactionTimeout(xaResourceTimeout);
+         }
+         catch (XAException e)
+         {
+            log.debugf(e, "XAException happend during return for: %s",
+                       getPool() != null ? getPool().getName() : "Unknown");
+         }
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public void enlist() throws SystemException
+   {
+      // This method is a bit convulted, but it has to be such because
+      // there is a race condition in the transaction manager where it
+      // unlocks during the enlist of the XAResource. It does this
+      // to avoid distributed deadlocks and to ensure the transaction
+      // timeout can fail a badly behaving resource during the enlist.
+      //
+      // When two threads in the same transaction are trying to enlist
+      // connections they could be from the same resource manager
+      // or even the same connection when tracking the connection by transaction.
+      //
+      // For the same connection, we only want to do the real enlist once.
+      // For two connections from the same resource manager we don't
+      // want the join before the initial start request.
+      //
+      // The solution is to build up a list of unenlisted resources
+      // in the TransactionSynchronizer and then choose one of the
+      // threads that is contending in the transaction to enlist them
+      // in order. The actual order doesn't really matter as it is the
+      // transaction manager that calculates the enlist flags and determines
+      // whether the XAResource was already enlisted.
+      //
+      // Once there are no unenlisted resources the threads are released
+      // to return the result of the enlistments.
+      //
+      // In practice, a thread just takes a snapshot to try to avoid one
+      // thread having to do all the work. If it did not do them all
+      // the next waiting thread will do the next snapshot until there
+      // there is either no snapshot or no waiting threads.
+      //
+      // A downside to this design is a thread could have its resource enlisted by
+      // an earlier thread while it enlists some later thread's resource.
+      // Since they are all a part of the same transaction, this is probably
+      // not a real issue.
+
+      // If we are already enlisted there is no reason to check again, as this method
+      // could be called multiple times during a transaction lifecycle.
+      // We know that we can only be inside this method if we are allowed to
+      if (isEnlisted() || getState().equals(ConnectionState.DESTROY) || getState().equals(ConnectionState.DESTROYED))
+         return;
+
+      // No transaction associated with the thread
+      TransactionManager tm = getConnectionManager().getTransactionIntegration().getTransactionManager();
+      int status = tm.getStatus();
+
+      if (status == Status.STATUS_NO_TRANSACTION)
+      {
+         if (transactionSynchronization != null && transactionSynchronization.currentTx != null)
+         {
+            String error = "Attempt to use connection outside a transaction when already a tx!";
+            log.tracef("%s %s", error, this);
+            
+
+            throw new IllegalStateException(error);
+         }
+         log.tracef("No transaction, no need to enlist: %s", this);
+
+         return;
+      }
+
+      // Inactive transaction
+      Transaction threadTx = tm.getTransaction();
+      if (threadTx == null || status != Status.STATUS_ACTIVE)
+      {
+         TxConnectionManager txConnectionManager = (TxConnectionManager)getConnectionManager();
+
+         if (!txConnectionManager.isAllowMarkedForRollback())
+         {
+            String error = "Transaction " + threadTx + " is not active " + TxUtils.getStatusAsString(status);
+            log.tracef("%s cl=%s", error, this);
+
+            throw new IllegalStateException(error);
+         }
+      }
+
+      log.tracef("Pre-enlist: %s threadTx=%s", this, threadTx);
+
+      // Our synchronization
+      TransactionSynchronization ourSynchronization = null;
+
+      // Serializes enlistment when two different threads are enlisting
+      // different connections in the same transaction concurrently
+      TransactionSynchronizer synchronizer = null;
+
+      try
+      {
+         TransactionSynchronizer.lock(threadTx,
+                                      getConnectionManager().getTransactionIntegration());
+      }
+      catch (Exception e)
+      {
+         setTrackByTx(false);
+         TxConnectionManagerImpl.rethrowAsSystemException("Exception during lock", threadTx, e);
+      }
+
+      try
+      {
+         // Interleaving should have an unenlisted transaction
+         // TODO We should be able to do some sharing shouldn't we?
+         if (!isTrackByTx() && transactionSynchronization != null)
+         {
+            String error = "Can't enlist - already a tx!";
+            log.tracef("%s %s", error, this);
+            throw new IllegalStateException(error);
+         }
+
+         // Check for different transaction
+         if (transactionSynchronization != null && !transactionSynchronization.currentTx.equals(threadTx))
+         {
+            String error = "Trying to change transaction " + threadTx + " in enlist!";
+            log.tracef("%s %s", error, this);
+            throw new IllegalStateException(error);
+         }
+
+         // Get the synchronizer
+         try
+         {
+            log.tracef("Get synchronizer %s threadTx=%s", this, threadTx);
+
+            synchronizer =
+               TransactionSynchronizer.getRegisteredSynchronizer(threadTx,
+                  getConnectionManager().getTransactionIntegration());
+         }
+         catch (Throwable t)
+         {
+            setTrackByTx(false);
+            TxConnectionManagerImpl.rethrowAsSystemException("Cannot register synchronization", threadTx, t);
+         }
+
+         // First time through, create a transaction synchronization
+         if (transactionSynchronization == null)
+         {
+            TransactionSynchronization synchronization = new TransactionSynchronization(threadTx, isTrackByTx());
+            synchronizer.addUnenlisted(synchronization);
+            transactionSynchronization = synchronization;
+         }
+
+         ourSynchronization = transactionSynchronization;
+      }
+      finally
+      {
+         TransactionSynchronizer.unlock(threadTx, getConnectionManager().getTransactionIntegration());
+      }
+
+      // Perform the enlistment(s)
+      List unenlisted = synchronizer.getUnenlisted();
+      if (unenlisted != null)
+      {
+         try
+         {
+            int size = unenlisted.size();
+            for (int i = 0; i < size; ++i)
+            {
+               TransactionSynchronization sync = (TransactionSynchronization) unenlisted.get(i);
+               if (sync.enlist())
+               {
+                  synchronizer.addEnlisted(sync);
+               }
+            }
+         }
+         finally
+         {
+            synchronizer.enlisted();
+         }
+      }
+
+      // What was the result of our enlistment?
+      log.tracef("Check enlisted %s threadTx=%s", this, threadTx);
+
+      ourSynchronization.checkEnlisted();
+      setEnlisted(true);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public boolean delist() throws ResourceException
+   {
+      log.tracef("delisting %s", this);
+
+      boolean success = true;
+
+      try
+      {
+         if (!isTrackByTx())
+         {
+            if (transactionSynchronization != null)
+            {
+               // SUSPEND
+               Transaction tx = transactionSynchronization.currentTx;
+               TransactionSynchronization synchronization = transactionSynchronization;
+               transactionSynchronization = null;
+               if (TxUtils.isUncommitted(tx))
+               {
+                  if (synchronization.enlisted)
+                  {
+                     TransactionSynchronizer synchronizer =
+                        TransactionSynchronizer.getRegisteredSynchronizer(tx,
+                                                                          getConnectionManager().
+                                                                          getTransactionIntegration());
+
+                     if (!synchronizer.removeEnlisted(synchronization))
+                     {
+                        log.tracef("%s not found in %s", synchronization, synchronizer);
+                     }   
+                  }
+
+                  if (!getState().equals(ConnectionState.DESTROYED))
+                  {
+                     log.tracef("delistResource(%s, TMSUSPEND)", getXAResource());
+
+                     boolean suspendResult = tx.delistResource(getXAResource(), XAResource.TMSUSPEND);
+
+                     if (Tracer.isEnabled())
+                        Tracer.delistConnectionListener(getPool() != null ? getPool().getName() : null,
+                                                        getManagedConnectionPool(),
+                                                        this, tx.toString(),
+                                                        suspendResult, false, true);
+
+                     if (!suspendResult)
+                     {
+                        throw new ResourceException(bundle.failureDelistResource(this));
+                     }
+                     else
+                     {
+                        log.tracef("delist-suspend: %s", this);
+                     }
+                  }
+               }
+            }
+            else
+            {
+               // SUCCESS / FAIL
+               if (!getState().equals(ConnectionState.DESTROYED) &&
+                   isManagedConnectionFree() &&
+                   isEnlisted() &&
+                   doDelistResource)
+               {
+                  if (getConnectionManager().getTransactionIntegration() != null &&
+                      getConnectionManager().getTransactionIntegration().getTransactionManager() != null)
+                  {
+                     Transaction tx = getConnectionManager().getTransactionIntegration().
+                        getTransactionManager().getTransaction();
+
+                     if (TxUtils.isUncommitted(tx))
+                     {
+                        if (TxUtils.isActive(tx))
+                        {
+                           log.tracef("delistResource(%s, TMSUCCESS)", getXAResource());
+
+                           boolean successResult = tx.delistResource(getXAResource(), XAResource.TMSUCCESS);
+
+                           if (Tracer.isEnabled())
+                              Tracer.delistConnectionListener(getPool() != null ? getPool().getName() : null,
+                                                              getManagedConnectionPool(),
+                                                              this, tx.toString(),
+                                                              true, false, true);
+
+                           if (successResult)
+                           {
+                              log.tracef("delist-success: %s", this);
+                           }
+                           else
+                           {
+                              log.debugf("delist-success failed: %s", this);
+                              success = false;
+                           }
+                        }
+                        else
+                        {
+                           log.tracef("delistResource(%s, TMFAIL)", getXAResource());
+
+                           boolean failResult = tx.delistResource(getXAResource(), XAResource.TMFAIL);
+                           
+                           if (Tracer.isEnabled())
+                              Tracer.delistConnectionListener(getPool() != null ? getPool().getName() : null,
+                                                              getManagedConnectionPool(),
+                                                              this, tx.toString(),
+                                                              false, false, true);
+
+                           if (failResult)
+                           {
+                              log.tracef("delist-fail: %s", this);
+                           }
+                           else
+                           {
+                              log.debugf("delist-fail failed: %s", this);
+
+                              success = false;
+                           }
+                        }
+                     }
+                  }
+               }
+            }
+
+            setEnlisted(false);
+         }
+
+         log.tracef("delisted %s", this);
+
+         return success;
+      }
+      catch (ResourceException re)
+      {
+         throw re;
+      }
+      catch (Throwable t)
+      {
+         throw new ResourceException(bundle.errorInDelist(), t);
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public void dissociate() throws ResourceException
+   {
+      log.tracef("dissociate: %s", this);
+
+      try
+      {
+         TransactionManager tm = getConnectionManager().getTransactionIntegration().getTransactionManager();
+         int status = tm.getStatus();
+
+         log.tracef("dissociate: status=%s", TxUtils.getStatusAsString(status));
+
+         if (status != Status.STATUS_NO_TRANSACTION)
+         {
+            if (isEnlisted())
+            {
+               if (doDelistResource)
+               {
+                  Transaction tx = tm.getTransaction();
+                  boolean delistResult = tx.delistResource(getXAResource(), XAResource.TMSUCCESS);
+
+                  log.tracef("dissociate: delistResult=%s", delistResult);
+               }
+            }
+            else
+            {
+               log.tracef("dissociate: not enlisted (%s)", this);
+            }
+
+            if (isTrackByTx())
+            {
+               ManagedConnectionPool mcp = getManagedConnectionPool();
+               TransactionSynchronizationRegistry tsr =
+                  getConnectionManager().getTransactionIntegration().getTransactionSynchronizationRegistry();
+
+               Lock lock = (Lock)tsr.getResource(LockKey.INSTANCE);
+               if (lock != null)
+               {
+                  try
+                  {
+                     lock.lockInterruptibly();
+                  }
+                  catch (InterruptedException ie)
+                  {
+                     Thread.interrupted();
+                     
+                     throw new ResourceException(bundle.unableObtainLock(), ie);
+                  }
+
+                  try
+                  {
+                     tsr.putResource(mcp, null);
+                  }
+                  finally
+                  {
+                     lock.unlock();
+                  }
+               }
+            }
+         }
+
+         localTransaction.set(false);
+         setTrackByTx(false);
+      
+         if (transactionSynchronization != null)
+         {
+            transactionSynchronization.cancel();
+            transactionSynchronization = null;
+         }
+
+         setEnlisted(false);
+      }
+      catch (Throwable t)
+      {
+         throw new ResourceException(bundle.errorInDissociate(), t);
+      }
+   }
+
+   //local will return this, xa will return one from mc.
+   /**
+    * Get XA resource.
+    * @return xa resource
+    */
+   protected XAResource getXAResource()
+   {
+      return xaResource;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public void connectionClosed(ConnectionEvent ce)
+   {
+      log.tracef("connectionClosed called mc=%s", this.getManagedConnection());
+      if (this.getManagedConnection() != (ManagedConnection)ce.getSource())
+         throw new IllegalArgumentException("ConnectionClosed event received from wrong ManagedConnection! Expected: " +
+               this.getManagedConnection() + ", actual: " + ce.getSource());
+
+      if (getCachedConnectionManager() != null)
+      {
+         try
+         {
+            this.getCachedConnectionManager().unregisterConnection(this.getConnectionManager(), this,
+                                                                   ce.getConnectionHandle());
+         }
+         catch (Throwable t)
+         {
+            log.throwableFromUnregisterConnection(t);
+         }
+      }
+
+      try
+      {
+         if (wasFreed(ce.getConnectionHandle()))
+         {
+            boolean success = delist();
+
+            log.tracef("isManagedConnectionFree=true mc=%s", this.getManagedConnection());
+
+            if (success || (tracking != null && !tracking.booleanValue()))
+            {
+               this.getConnectionManager().returnManagedConnection(this, false);
+            }
+            else
+            {
+               log.delistingFailed(getPool() != null ? getPool().getName() : "Unknown", new Exception());
+               this.getConnectionManager().returnManagedConnection(this, true);
+            }
+         }
+         else
+         {
+            log.tracef("isManagedConnectionFree=false mc=%s", this.getManagedConnection());
+         }
+      }
+      catch (Throwable t)
+      {
+         log.errorWhileClosingConnectionHandle(t);
+         this.getConnectionManager().returnManagedConnection(this, true);
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public void localTransactionStarted(ConnectionEvent ce)
+   {
+      localTransaction.set(true);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public void localTransactionCommitted(ConnectionEvent ce)
+   {
+      localTransaction.set(false);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public void localTransactionRolledback(ConnectionEvent ce)
+   {
+      localTransaction.set(false);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public void tidyup() throws ResourceException
+   {
+      // We have a hanging transaction
+      if (localTransaction.get())
+      {
+         LocalTransaction local = null;
+         ManagedConnection mc = getManagedConnection();
+         try
+         {
+            local = mc.getLocalTransaction();
+         }
+         catch (Throwable t)
+         {
+            throw new ResourceException(bundle.unfinishedLocalTransaction(this), t);
+         }
+         if (local == null)
+            throw new ResourceException(bundle.unfinishedLocalTransactionNotProvideLocalTransaction(this));
+         else
+         {
+            local.rollback();
+            log.debugf("Unfinished local transaction was rolled back.%s", this);
+         }
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   void haltCatchFire()
+   {
+      if (isEnlisted())
+      {
+         if (transactionSynchronization != null)
+            transactionSynchronization.cancel();
+
+         String txId = "";
+
+         if (getConnectionManager().getTransactionIntegration() != null &&
+             getConnectionManager().getTransactionIntegration().getTransactionManager() != null)
+         {
+            Transaction tx = null;
+            try
+            {
+               tx = getConnectionManager().getTransactionIntegration().getTransactionManager().getTransaction();
+
+               if (Tracer.isEnabled() && tx != null)
+                  txId = tx.toString();
+               
+               if (TxUtils.isUncommitted(tx) && doDelistResource)
+               {
+                  log.tracef("connectionErrorOccurred: delistResource(%s, TMFAIL)", getXAResource());
+
+                  boolean failResult = tx.delistResource(getXAResource(), XAResource.TMFAIL);
+                  
+                  if (failResult)
+                  {
+                     log.tracef("connectionErrorOccurred: delist-fail: %s", this);
+                  }
+                  else
+                  {
+                     log.debugf("connectionErrorOccurred: delist-fail failed: %s", this);
+                  }
+               }
+            }
+            catch (Exception e)
+            {
+               log.debugf(e, "connectionErrorOccurred: Exception during delistResource=%s", e.getMessage());
+            }
+            finally
+            {
+               if (TxUtils.isUncommitted(tx) && doSetRollbackOnly)
+               {
+                  try
+                  {
+                     tx.setRollbackOnly();
+                  }
+                  catch (Exception e)
+                  {
+                     // Just a hint
+                  }
+               }
+            }
+         }
+         
+         if (Tracer.isEnabled())
+         {
+            Tracer.delistConnectionListener(getPool() != null ? getPool().getName() : null,
+                                            getManagedConnectionPool(),
+                                            this, txId, false, true, false);
+         }
+      }
+
+      // Prepare to explode
+      setEnlisted(false);
+      transactionSynchronization = null;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   //Important method!!
+   @Override
+   public boolean isManagedConnectionFree()
+   {
+      if (isTrackByTx() && transactionSynchronization != null)
+         return false;
+      return super.isManagedConnectionFree();
+   }
+
+   /**
+    * This method changes the number of handles or
+    * the track-by-tx value depending on the parameter passed in
+    * @param handle The handle; if null track-by-tx is changed
+    * @return True if the managed connection was freed
+    */
+   boolean wasFreed(Object handle)
+   {
+      if (handle != null)
+      {
+         // Unregister the handle
+         unregisterConnection(handle);
+      }
+      else
+      {
+         if (!isTrackByTx())
+         {
+            // Only change the state once
+            return false;
+         }
+
+         // Set track-by-tx to false
+         setTrackByTx(false);
+      }
+
+      // Return if the managed connection was just freed
+      return isManagedConnectionFree();
+   }
+
+   /**
+    * Transaction sync. class.
+    * Please note this class has public access is for test purposes only.
+    * Except for test purposes it should be considered private!
+    * Don't use it outside enclosing class or testcase!
+    */
+   public class TransactionSynchronization implements Synchronization
+   {
+      /**Error message*/
+      private final Throwable failedToEnlist;
+
+      /** Record enlist */
+      private final boolean recordEnlist;
+
+      /** Transaction */
+      protected final Transaction currentTx;
+
+      /** This is the status when we were registered */
+      private final boolean wasTrackByTx;
+
+      /** Whether we are enlisted */
+      private boolean enlisted;
+
+      /** Any error during enlistment */
+      private Throwable enlistError;
+
+      /** Cancel */
+      private boolean cancel;
+
+      /**
+       * Create a new TransactionSynchronization.transaction
+       * @param tx transaction
+       *
+       * @param trackByTx whether this is track by connection
+       */
+      public TransactionSynchronization(final Transaction tx, final boolean trackByTx)
+      {
+         this.currentTx = tx;
+         this.wasTrackByTx = trackByTx;
+         this.enlisted = false;
+         this.enlistError = null;
+         this.cancel = false;
+
+         if (TxConnectionListener.this.enlistmentTrace != null)
+         {
+            this.recordEnlist = TxConnectionListener.this.enlistmentTrace.booleanValue();
+         }
+         else
+         {
+            this.recordEnlist = !disableFailedtoEnlist;
+         }
+         
+         if (this.recordEnlist)
+         {
+            this.failedToEnlist = new Throwable("Unabled to enlist resource, see the previous warnings.");
+         }
+         else
+         {
+            this.failedToEnlist = null;
+         }
+
+         log.tracef("%s: Constructor", toString());
+      }
+
+      /**
+       * Set the cancel flag
+       */
+      public void cancel()
+      {
+         cancel = true;
+      }
+
+      /**
+       * Get the result of the enlistment.
+       *
+       * @throws SystemException for any error
+       */
+      public void checkEnlisted() throws SystemException
+      {
+         if (this.enlistError != null)
+         {
+            String error = "Error enlisting resource in transaction=" + this.currentTx;
+            log.tracef("%s %s", error, TxConnectionListener.this);
+
+            // Wrap the error to give a reasonable stacktrace since the resource
+            // could have been enlisted by a different thread
+            if (recordEnlist && enlistError == failedToEnlist)
+            {
+               SystemException se =
+                  new SystemException(bundle.systemExceptionWhenFailedToEnlistEqualsCurrentTx(
+                     failedToEnlist, this.currentTx));
+
+               if (Tracer.isEnabled())
+                  Tracer.exception(getPool() != null ? getPool().getName() : null, 
+                                   getManagedConnectionPool(),
+                                   TxConnectionListener.this, se);
+
+               throw se;
+
+            }
+            else
+            {
+               SystemException e = new SystemException(error);
+               e.initCause(enlistError);
+
+               if (Tracer.isEnabled())
+                  Tracer.exception(getPool() != null ? getPool().getName() : null, 
+                                   getManagedConnectionPool(),
+                                   TxConnectionListener.this, e);
+
+               throw e;
+            }
+         }
+         if (!enlisted)
+         {
+            String error = "Resource is not enlisted in transaction=" + currentTx;
+            log.tracef("%s %s", error, TxConnectionListener.this);
+            throw new IllegalStateException("Resource was not enlisted.");
+         }
+      }
+
+      /**
+       * Enlist the resource
+       *
+       * @return true when enlisted, false otherwise
+       */
+      public boolean enlist()
+      {
+         log.tracef("Enlisting resource %s", TxConnectionListener.this);
+         try
+         {
+            XAResource resource = getXAResource();
+            if (!currentTx.enlistResource(resource))
+            {
+               if (Tracer.isEnabled())
+                  Tracer.enlistConnectionListener(getPool() != null ? getPool().getName() : null, 
+                                                  getManagedConnectionPool(),
+                                                  TxConnectionListener.this, currentTx.toString(), false,
+                                                  !TxConnectionListener.this.isTrackByTx());
+
+               if (recordEnlist)
+               {
+                  enlistError = failedToEnlist;
+               }
+               else
+               {
+                  enlistError = new Throwable("Failed to enlist");
+               }
+            }
+            else
+            {
+               if (Tracer.isEnabled())
+                  Tracer.enlistConnectionListener(getPool() != null ? getPool().getName() : null,
+                                                  getManagedConnectionPool(),
+                                                  TxConnectionListener.this, currentTx.toString(), true,
+                                                  !TxConnectionListener.this.isTrackByTx());
+            }
+         }
+         catch (Throwable t)
+         {
+            enlistError = t;
+
+            if (Tracer.isEnabled())
+               Tracer.enlistConnectionListener(getPool() != null ? getPool().getName() : null,
+                                               getManagedConnectionPool(),
+                                               TxConnectionListener.this, currentTx.toString(), false,
+                                               !TxConnectionListener.this.isTrackByTx());
+            }
+
+         synchronized (this)
+         {
+            if (enlistError != null)
+            {
+               if (log.isTraceEnabled())
+               {
+                  log.trace("Failed to enlist resource " + TxConnectionListener.this, enlistError);
+               }
+
+               setTrackByTx(false);
+               transactionSynchronization = null;
+
+               return false;
+            }
+
+            enlisted = true;
+
+            log.tracef("Enlisted resource %s", TxConnectionListener.this);
+
+            return true;
+         }
+      }
+
+      /**
+       * {@inheritDoc}
+       */
+      public void beforeCompletion()
+      {
+         if (enlisted && !cancel)
+         {
+            try
+            {
+               if (this.equals(transactionSynchronization) && wasTrackByTx && doDelistResource)
+               {
+                  if (TxUtils.isUncommitted(currentTx))
+                  {
+                     if (TxUtils.isActive(currentTx))
+                     {
+                        log.tracef("delistResource(%s, TMSUCCESS)", TxConnectionListener.this.getXAResource());
+
+                        currentTx.delistResource(TxConnectionListener.this.getXAResource(), XAResource.TMSUCCESS);
+
+                        if (Tracer.isEnabled())
+                           Tracer.delistConnectionListener(getPool() != null ? getPool().getName() : null,
+                                                           getManagedConnectionPool(),
+                                                           TxConnectionListener.this, currentTx.toString(),
+                                                           true, false, false);
+                     }
+                     else
+                     {
+                        log.tracef("delistResource(%s, TMFAIL)", TxConnectionListener.this.getXAResource());
+
+                        currentTx.delistResource(TxConnectionListener.this.getXAResource(), XAResource.TMFAIL);
+
+                        if (Tracer.isEnabled())
+                           Tracer.delistConnectionListener(getPool() != null ? getPool().getName() : null,
+                                                           getManagedConnectionPool(),
+                                                           TxConnectionListener.this, currentTx.toString(),
+                                                           false, false, false);
+                     }
+                  }
+                  else
+                  {
+                     if (log.isTraceEnabled())
+                         log.tracef("Non-uncommitted transaction for %s (%s)", TxConnectionListener.this,
+                                   currentTx != null ? TxUtils.getStatusAsString(currentTx.getStatus()) : "None");
+                  }
+               }
+               else
+               {
+                  log.tracef("No delistResource for: %s", TxConnectionListener.this);
+               }
+            }
+            catch (Throwable t)
+            {
+               log.beforeCompletionErrorOccured(TxConnectionListener.this, t);
+            }
+         }
+         else
+         {
+            log.tracef("Unenlisted resource: %s", TxConnectionListener.this);
+         }
+      }
+
+      /**
+       * {@inheritDoc}
+       */
+      public void afterCompletion(int status)
+      {
+         // The connection got destroyed during the transaction
+         if (getState().equals(ConnectionState.DESTROYED))
+         {
+            return;
+         }
+
+         if (!cancel)
+         {
+            // Are we still in the original transaction?
+            if (!this.equals(transactionSynchronization))
+            {
+               // If we are interleaving transactions we have nothing to do
+               if (!wasTrackByTx)
+               {
+                  TxConnectionListener.this.setEnlisted(false);
+                  return;
+               }
+               else
+               {
+                  // There is something wrong with the pooling
+                  String message = "afterCompletion called with wrong tx! Expected: " +
+                     this + ", actual: " + transactionSynchronization;
+                  IllegalStateException e = new IllegalStateException(message);
+                  log.somethingWrongWithPooling(e);
+               }
+            }
+            // "Delist"
+            TxConnectionListener.this.setEnlisted(false);
+            transactionSynchronization = null;
+
+            // This is where we close when doing track by transaction
+            if (wasTrackByTx)
+            {
+               log.tracef("afterCompletion(%d) isTrackByTx=%b for %s" 
+                          , status, isTrackByTx(), TxConnectionListener.this);
+
+               if (wasFreed(null))
+               {
+                  if (Tracer.isEnabled() && status == Status.STATUS_ROLLEDBACK)
+                     Tracer.delistConnectionListener(getPool() != null ? getPool().getName() : null,
+                                                     getManagedConnectionPool(),
+                                                     TxConnectionListener.this, "", true, true, false);
+
+                  getConnectionManager().returnManagedConnection(TxConnectionListener.this, false);
+               }
+               else
+               {
+                  if (tracking == null || tracking.booleanValue())
+                  {
+                     log.activeHandles(getPool() != null ? getPool().getName() : "Unknown", connectionHandles.size());
+
+                     if (tracking != null && tracking.booleanValue())
+                     {
+                        Iterator> it = connectionTraces.entrySet().iterator();
+                        while (it.hasNext())
+                        {
+                           Map.Entry entry = it.next();
+                           log.activeHandle(entry.getKey(), entry.getValue());
+                        }
+
+                        log.txConnectionListenerBoundary(new Exception());
+                     }
+
+                     if (Tracer.isEnabled())
+                     {
+                        for (Object c : connectionHandles)
+                        {
+                           Tracer.clearConnection(getPool() != null ? getPool().getName() : null,
+                                                  getManagedConnectionPool(),
+                                                  TxConnectionListener.this, c);
+                        }
+                     }
+
+                     getConnectionManager().returnManagedConnection(TxConnectionListener.this, true);
+                  }
+                  else
+                  {
+                     if (log.isTraceEnabled())
+                        log.tracef(new Exception("Connection across boundary"), "ConnectionListener=%s",
+                                   TxConnectionListener.this);
+                  }
+               }
+            }
+         }
+      }
+
+      /**
+       * {@inheritDoc}
+       */
+      @Override
+      public String toString()
+      {
+         StringBuffer buffer = new StringBuffer();
+         buffer.append("TransactionSynchronization@").append(System.identityHashCode(this));
+         buffer.append("{tx=").append(currentTx);
+         buffer.append(" wasTrackByTx=").append(wasTrackByTx);
+         buffer.append(" enlisted=").append(enlisted);
+         buffer.append(" cancel=").append(cancel);
+         buffer.append("}");
+         return buffer.toString();
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   // For debugging
+   @Override
+   protected void toString(StringBuffer buffer)
+   {
+      buffer.append(" xaResource=").append(xaResource);
+      buffer.append(" txSync=").append(transactionSynchronization);
+   }
+
+   /**
+    * Get the transactionSynchronization.
+    * Please note this package protected method is for test purposes only. Don't use it!
+    *
+    * @return the transactionSynchronization.
+    */
+   final TransactionSynchronization getTransactionSynchronization()
+   {
+      return transactionSynchronization;
+   }
+
+   /**
+    * Set the transactionSynchronization.
+    * Please note this package protected method is for test purposes only. Don't use it!
+    *
+    * @param transactionSynchronization The transactionSynchronization to set.
+    */
+   final void setTransactionSynchronization(TransactionSynchronization transactionSynchronization)
+   {
+      this.transactionSynchronization = transactionSynchronization;
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/package.html
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/package.html	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/listener/package.html	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,3 @@
+
+This package contains the connection listener implementation.
+
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/notx/NoTxConnectionManagerImpl.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/notx/NoTxConnectionManagerImpl.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/notx/NoTxConnectionManagerImpl.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,107 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2008-2009, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager.notx;
+
+import org.jboss.jca.core.CoreBundle;
+import org.jboss.jca.core.CoreLogger;
+import org.jboss.jca.core.connectionmanager.AbstractConnectionManager;
+import org.jboss.jca.core.connectionmanager.ConnectionRecord;
+import org.jboss.jca.core.connectionmanager.NoTxConnectionManager;
+import org.jboss.jca.core.connectionmanager.listener.ConnectionListener;
+import org.jboss.jca.core.connectionmanager.listener.NoTxConnectionListener;
+import org.jboss.jca.core.connectionmanager.pool.mcp.ManagedConnectionPool;
+import org.jboss.jca.core.spi.transaction.TransactionIntegration;
+
+import java.util.Collection;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.ManagedConnection;
+import javax.transaction.SystemException;
+
+import org.jboss.logging.Logger;
+import org.jboss.logging.Messages;
+
+/**
+ * Non transactional connection manager implementation.
+ *
+ * @author Gurkan Erdogdu 
+ * @author Jesper Pedersen 
+ */
+public class NoTxConnectionManagerImpl extends AbstractConnectionManager implements NoTxConnectionManager
+{
+   /** The logger */
+   private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, NoTxConnectionManager.class.getName());
+
+   /** The bundle */
+   private static CoreBundle bundle = Messages.getBundle(CoreBundle.class);
+ 
+   /** Serial version uid */
+   private static final long serialVersionUID = 1L;
+
+   /**
+    * Default constructor.
+    */
+   public NoTxConnectionManagerImpl()
+   {
+   }
+
+   /**
+    * Get the logger.
+    * @return The value
+    */
+   protected CoreLogger getLogger()
+   {
+      return log;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public ConnectionListener createConnectionListener(ManagedConnection managedConnection, ManagedConnectionPool mcp)
+      throws ResourceException
+   {
+      ConnectionListener cli = new NoTxConnectionListener(this, managedConnection, getPool(), 
+                                                          mcp, getFlushStrategy(), getTracking());
+      managedConnection.addConnectionEventListener(cli);
+
+      return cli;
+   }
+
+   @Override
+   public void transactionStarted(Collection conns) throws SystemException
+   {
+      // Doing nothing
+   }
+
+   @Override
+   public TransactionIntegration getTransactionIntegration()
+   {
+      return null;
+   }
+
+   @Override
+   public boolean isTransactional()
+   {
+      return false;
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/notx/package.html
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/notx/package.html	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/notx/package.html	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,3 @@
+
+This package contains the non-tx connection manager implementation.
+
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/package.html
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/package.html	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/package.html	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,3 @@
+
+This package contains the connection manager implementation.
+
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/AbstractPool.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/AbstractPool.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/AbstractPool.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,1176 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2013, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager.pool;
+
+import org.jboss.jca.core.CoreBundle;
+import org.jboss.jca.core.CoreLogger;
+import org.jboss.jca.core.api.connectionmanager.pool.FlushMode;
+import org.jboss.jca.core.api.connectionmanager.pool.PoolConfiguration;
+import org.jboss.jca.core.api.connectionmanager.pool.PoolStatistics;
+import org.jboss.jca.core.connectionmanager.ConnectionManager;
+import org.jboss.jca.core.connectionmanager.TxConnectionManager;
+import org.jboss.jca.core.connectionmanager.listener.ConnectionListener;
+import org.jboss.jca.core.connectionmanager.pool.api.Capacity;
+import org.jboss.jca.core.connectionmanager.pool.api.Pool;
+import org.jboss.jca.core.connectionmanager.pool.api.Semaphore;
+import org.jboss.jca.core.connectionmanager.pool.capacity.DefaultCapacity;
+import org.jboss.jca.core.connectionmanager.pool.capacity.TimedOutDecrementer;
+import org.jboss.jca.core.connectionmanager.pool.mcp.ManagedConnectionPool;
+import org.jboss.jca.core.connectionmanager.pool.mcp.ManagedConnectionPoolFactory;
+import org.jboss.jca.core.connectionmanager.transaction.LockKey;
+import org.jboss.jca.core.spi.transaction.TransactionIntegration;
+import org.jboss.jca.core.tracer.Tracer;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.ConnectionRequestInfo;
+import javax.resource.spi.ManagedConnection;
+import javax.resource.spi.ManagedConnectionFactory;
+import javax.security.auth.Subject;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import javax.transaction.TransactionSynchronizationRegistry;
+
+import org.jboss.logging.Messages;
+
+/**
+ * Abstract pool implementation.
+ * 
+ * It can contains sub-pools according to the semantic of
+ * the pool. Concrete implementatins override {@link AbstractPool#getKey(Subject, ConnectionRequestInfo, boolean)}
+ * method to create map key object.
+ * 
+ * @author Gurkan Erdogdu 
+ * @author Jesper Pedersen 
+ */
+public abstract class AbstractPool implements Pool
+{
+   /** New line */
+   private static String newLine = SecurityActions.getSystemProperty("line.separator");
+
+   /** The logger */
+   protected final CoreLogger log;
+
+   /** The bundle */
+   private static CoreBundle bundle = Messages.getBundle(CoreBundle.class);
+   
+   /** The managed connection pools, maps key --> pool */
+   private final ConcurrentMap mcpPools =
+      new ConcurrentHashMap();
+
+   /** The managed connection factory for this pool */
+   private final ManagedConnectionFactory mcf;
+
+   /** The connection manager for this pool*/
+   private ConnectionManager cm;
+
+   /** The pool parameters */
+   private final PoolConfiguration poolConfiguration;
+
+   /** Whether to use separate pools for transactional and non-transaction use */
+   private final boolean noTxSeparatePools;
+
+   /** Shutdown */
+   private final AtomicBoolean shutdown = new AtomicBoolean(false);
+
+   /** The poolName */
+   private String poolName;
+
+   /** Statistics */
+   private PoolStatisticsImpl statistics;
+
+   /** The permits used to control who can checkout a connection */
+   private Semaphore permits;
+
+   /** Are the connections sharable */
+   private boolean sharable;
+
+   /** MCP class */
+   private String mcpClass;
+
+   /** The capacity */
+   private Capacity capacity;
+
+   /** Interleaving */
+   private boolean interleaving;
+
+   /** No lazy enlistment available */
+   private AtomicBoolean noLazyEnlistmentAvailable;
+   
+   /**
+    * Create a new base pool.
+    *
+    * @param mcf the managed connection factory
+    * @param pc the pool configuration
+    * @param noTxSeparatePools noTxSeparatePool
+    * @param sharable Are the connections sharable
+    * @param mcp mcp
+    */
+   protected AbstractPool(final ManagedConnectionFactory mcf, final PoolConfiguration pc,
+                          final boolean noTxSeparatePools, final boolean sharable,
+                          final String mcp)
+   {
+      if (mcf == null)
+         throw new IllegalArgumentException("MCF is null");
+
+      if (pc == null)
+         throw new IllegalArgumentException("PoolConfiguration is null");
+
+      this.mcf = mcf;
+      this.poolConfiguration = pc;
+      this.noTxSeparatePools = noTxSeparatePools;
+      this.sharable = sharable;
+      this.mcpClass = mcp;
+      this.log = getLogger();
+      this.statistics = new PoolStatisticsImpl(pc.getMaxSize());
+      this.permits = new Semaphore(pc.getMaxSize(), pc.isFair(), statistics);
+      this.capacity = null;
+      this.interleaving = false;
+      this.noLazyEnlistmentAvailable = new AtomicBoolean(false);
+   }
+
+   /**
+    * Sets pool name.
+    * @param poolName pool name
+    */
+   public void setName(String poolName)
+   {
+      this.poolName = poolName;
+   }
+
+   /**
+    * Gets pool name.
+    * @return pool name
+    */
+   public String getName()
+   {
+      return poolName;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public Semaphore getLock()
+   {
+      return permits;
+   }
+
+   /**
+    * Is sharable
+    * @return The value
+    */
+   public boolean isSharable()
+   {
+      return sharable;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public Capacity getCapacity()
+   {
+      if (capacity == null)
+         return DefaultCapacity.INSTANCE;
+
+      return capacity;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void setCapacity(Capacity c)
+   {
+      capacity = c;
+   }
+
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean isFIFO()
+   {
+      if (capacity == null || capacity.getDecrementer() == null ||
+          TimedOutDecrementer.class.getName().equals(capacity.getDecrementer().getClass().getName()))
+         return false;
+      
+      return true;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean isInterleaving()
+   {
+      return interleaving;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void setInterleaving(boolean v)
+   {
+      interleaving = v;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean isIdle()
+   {
+      for (ManagedConnectionPool mcp : mcpPools.values())
+      {
+         if (!mcp.isIdle())
+            return false;
+      }
+
+      return true;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean isFull()
+   {
+      return permits.availablePermits() == 0;
+   }
+
+   /**
+    * Retrieve the key for this request.
+    *
+    * @param subject the subject
+    * @param cri the connection request information
+    * @param separateNoTx separateNoTx
+    * @return the key
+    * @throws ResourceException for any error
+    */
+   protected abstract Object getKey(Subject subject, ConnectionRequestInfo cri,
+         boolean separateNoTx) throws ResourceException;
+
+   /**
+    * Determine the correct pool for this request,
+    * creates a new one when necessary.
+    *
+    * @param key the key to the pool
+    * @param subject the subject of the pool
+    * @param cri the connection request info
+    * @return the subpool context
+    * @throws ResourceException for any error
+    */
+   protected ManagedConnectionPool getManagedConnectionPool(Object key, Subject subject, ConnectionRequestInfo cri)
+      throws ResourceException
+   {
+      try
+      {
+         ManagedConnectionPool mcp = mcpPools.get(key);
+         if (mcp == null)
+         {
+            // Let sync, since it is expensive to create connections
+            synchronized (this)
+            {
+               mcp = mcpPools.get(key);
+
+               if (mcp == null)
+               {
+                  ManagedConnectionPoolFactory mcpf = new ManagedConnectionPoolFactory();
+                  ManagedConnectionPool newMcp = mcpf.create(mcpClass, mcf, cm, subject, cri, poolConfiguration, this);
+
+                  mcp = mcpPools.putIfAbsent(key, newMcp);
+                  if (mcp == null)
+                  {
+                     mcp = newMcp;
+
+                     if (Tracer.isEnabled())
+                        Tracer.createManagedConnectionPool(getName(), mcp);
+                     
+                     try
+                     {
+                        initLock();
+                     }
+                     catch (Throwable lockThrowable)
+                     {
+                        // Init later then
+                     }
+                  }
+                  else
+                  {
+                     // and shut them down again
+                     newMcp.shutdown();
+                  }
+
+                  log.tracef("%s: mcpPools=%s", getName(), mcpPools);
+               }
+            }
+         }
+
+         return mcp;
+      }
+      catch (Throwable t)
+      {
+         throw new ResourceException(bundle.unableGetManagedConnectionPool(), t);
+      }
+   }
+
+   /**
+    * Get any transaction integration associated with the pool.
+    *
+    * @return the transaction integration
+    */
+   protected TransactionIntegration getTransactionIntegration()
+   {
+      if (cm != null)
+         return cm.getTransactionIntegration();
+
+      return null;
+   }
+
+   /**
+    * Get any transaction manager associated with the pool.
+    *
+    * @return the transaction manager
+    */
+   protected TransactionManager getTransactionManager()
+   {
+      if (getTransactionIntegration() != null)
+         return getTransactionIntegration().getTransactionManager();
+
+      return null;
+   }
+
+   /**
+    * Get any transaction synchronization registry associated with the pool.
+    * @return The value
+    */
+   protected TransactionSynchronizationRegistry getTransactionSynchronizationRegistry()
+   {
+      if (getTransactionIntegration() != null)
+         return getTransactionIntegration().getTransactionSynchronizationRegistry();
+
+      return null;
+   }
+
+   /**
+    * Init lock
+    * @return The lock
+    */
+   private Lock initLock()
+   {
+      TransactionSynchronizationRegistry tsr = getTransactionSynchronizationRegistry();
+
+      if (tsr != null)
+         return initLock(tsr);
+
+      return null;
+   }
+
+   /**
+    * Init lock
+    * @param tsr The transaction synchronization registry
+    * @return The lock
+    */
+   private Lock initLock(TransactionSynchronizationRegistry tsr)
+   {
+      if (tsr.getTransactionKey() != null)
+      {
+         Lock lock = (Lock)tsr.getResource(LockKey.INSTANCE);
+         if (lock == null)
+         {
+            lock = new ReentrantLock(true);
+            tsr.putResource(LockKey.INSTANCE, lock);
+            return lock;
+         }
+         else
+         {
+            return lock;
+         }
+      }
+
+      return null;
+   }
+
+   /**
+    * Get TSR lock
+    * @return The lock; null if TX isn't active
+    */
+   private Lock getTSRLock()
+   {
+      Lock result = null;
+      try
+      {
+         TransactionSynchronizationRegistry tsr = getTransactionSynchronizationRegistry();
+
+         if (tsr != null && tsr.getTransactionKey() != null)
+         {
+            result = (Lock)tsr.getResource(LockKey.INSTANCE);
+            if (result == null)
+            {
+               result = initLock(tsr);
+            }
+         }
+      }
+      catch (Throwable t)
+      {
+         // Catch all exceptions
+      }
+
+      return result;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void emptyManagedConnectionPool(ManagedConnectionPool pool)
+   {
+      log.debugf("%s: emptyManagedConnectionPool(%s)", poolName, pool);
+
+      if (pool != null)
+      {
+         // We only consider removal if there are more than 1 managed connection pool
+         if (mcpPools.size() > 1 && pool.isEmpty())
+         {
+            if (mcpPools.values().remove(pool))
+            {
+               try
+               {
+                  pool.shutdown();
+               }
+               catch (Exception e)
+               {
+                  // Should not happen
+                  log.trace("MCP.shutdown: " + e.getMessage(), e);
+               }
+
+               if (Tracer.isEnabled())
+                  Tracer.destroyManagedConnectionPool(getName(), pool);
+                     
+               log.tracef("%s: mcpPools=%s", getName(), mcpPools);
+            }
+         }
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void flush()
+   {
+      flush(FlushMode.IDLE);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void flush(boolean kill)
+   {
+      if (!kill)
+      {
+         flush(FlushMode.IDLE);
+      }
+      else
+      {
+         flush(FlushMode.ALL);
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void flush(FlushMode mode)
+   {
+      final Collection removedConnectionListeners = new ArrayList();
+      synchronized (this)
+      {
+         log.debugf("%s: flush(%s)", poolName, mode);
+
+         Set clearMcpPools = new HashSet();
+         int size = mcpPools.size();
+
+         Iterator it = mcpPools.values().iterator();
+         while (it.hasNext())
+         {
+            ManagedConnectionPool mcp = it.next();
+            try
+            {
+               mcp.flush(mode, removedConnectionListeners);
+            }
+            catch (Exception e)
+            {
+               // Should not happen
+               log.trace("MCP.flush: " + e.getMessage(), e);
+            }
+
+            if (mcp.isEmpty() && !isPrefill() && size > 1)
+               clearMcpPools.add(mcp);
+         }
+
+         if (clearMcpPools.size() > 0)
+         {
+            for (ManagedConnectionPool mcp : clearMcpPools)
+            {
+               if (mcp.isEmpty())
+               {
+                  try
+                  {
+                     mcp.shutdown();
+                  }
+                  catch (Exception e)
+                  {
+                     // Should not happen
+                     log.trace("MCP.shutdown: " + e.getMessage(), e);
+                  }
+
+                  if (Tracer.isEnabled())
+                     Tracer.destroyManagedConnectionPool(getName(), mcp);
+
+                  mcpPools.values().remove(mcp);
+               }
+            }
+
+            log.tracef("%s: mcpPools=%s", getName(), mcpPools);
+         }
+      }
+      if (removedConnectionListeners != null)
+      {
+         removedConnectionListeners.parallelStream().forEach(cl ->{
+            log.tracef("Destroying flushed connection %s", cl);
+
+            if (Tracer.isEnabled())
+               Tracer.destroyConnectionListener(getName(), cl.getManagedConnectionPool(), cl, false, false, false, true,
+                     false, false, false, Tracer.isRecordCallstacks() ? new Throwable("CALLSTACK") : null);
+            cl.destroy();
+         });
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public ConnectionListener getConnection(Transaction trackByTransaction, Subject subject, ConnectionRequestInfo cri)
+      throws ResourceException
+   {
+      ConnectionListener cl = null;
+      boolean separateNoTx = false;
+
+      if (shutdown.get())
+         throw new ResourceException(bundle.connectionManagerIsShutdown(poolName));
+
+      if (noTxSeparatePools)
+      {
+         separateNoTx = cm.isTransactional();
+      }
+
+      // Get specific managed connection pool key
+      Object key = getKey(subject, cri, separateNoTx);
+
+      // Get managed connection pool
+      ManagedConnectionPool mcp = getManagedConnectionPool(key, subject, cri);
+
+      // Are we doing track by transaction ?
+      TransactionSynchronizationRegistry tsr = getTransactionSynchronizationRegistry();
+      Object transactionKey = tsr != null ? tsr.getTransactionKey() : null;
+
+      if (trackByTransaction == null || transactionKey == null)
+      {
+         return getSimpleConnection(subject, cri, mcp);
+      }
+
+      // Transaction old connections
+      cl = getTransactionOldConnection(trackByTransaction, mcp);
+
+      // Creates a new connection with given transaction
+      if (cl == null)
+      {
+         cl = getTransactionNewConnection(trackByTransaction, mcp, subject, cri);
+      }
+
+      return cl;
+   }
+
+   /**
+    * Gets simple connection listener that wraps connection.
+    * @param subject Subject instance
+    * @param cri Connection request info
+    * @param mcp The managed connection pool
+    * @return connection listener
+    * @throws ResourceException ResourceException
+    */
+   private ConnectionListener getSimpleConnection(final Subject subject, final ConnectionRequestInfo cri,
+                                                  final ManagedConnectionPool mcp)
+      throws ResourceException
+   {
+      // Get connection from the managed connection pool
+      ConnectionListener cl = mcp.getConnection(subject, cri);
+
+      log.tracef("Got connection from pool: %s", cl);
+
+      if (cm instanceof TxConnectionManager && cm.getCachedConnectionManager() == null &&
+          noLazyEnlistmentAvailable.compareAndSet(false, true))
+         log.noLazyEnlistmentAvailable(poolName);
+      
+      return cl;
+   }
+
+   /**
+    * Gets connection listener instance associated with transaction.
+    * This method is package protected beacause it is intended only for test case use.
+    * Please don't use it in your production code.
+    * @param trackByTransaction transaction instance
+    * @param mcp the managed connection pool associated with the desired connection listener
+    * @return connection listener instance
+    * @throws ResourceException Thrown if an error occurs
+    */
+   ConnectionListener getTransactionOldConnection(Transaction trackByTransaction, ManagedConnectionPool mcp)
+      throws ResourceException
+   {
+      TransactionSynchronizationRegistry tsr = getTransactionSynchronizationRegistry();
+      Lock lock = getTSRLock();
+
+      if (lock == null)
+         throw new ResourceException(bundle.unableObtainLock());
+
+      try
+      {
+         lock.lockInterruptibly();
+      }
+      catch (InterruptedException ie)
+      {
+         Thread.interrupted();
+         
+         throw new ResourceException(bundle.unableObtainLock(), ie);
+      }
+      try
+      {
+         // Already got one
+         ConnectionListener cl = (ConnectionListener)tsr.getResource(mcp);
+         if (cl != null)
+         {
+            log.tracef("Previous connection tracked by transaction=%s tx=%s", cl, trackByTransaction);
+            return cl;
+         }
+
+         return null;
+      }
+      catch (Throwable t)
+      {
+         throw new ResourceException(bundle.unableGetConnectionListener(), t);
+      }
+      finally
+      {
+         lock.unlock();
+      }
+   }
+
+   /**
+    * Gets new connection listener if necessary instance with transaction.
+    * This method is package protected beacause it is intended only for test case use.
+    * Please don't use it in your production code.
+    * @param trackByTransaction transaction instance
+    * @param mcp pool instance
+    * @param subject subject instance
+    * @param cri connection request info
+    * @return connection listener instance
+    * @throws ResourceException ResourceException
+    */
+   ConnectionListener getTransactionNewConnection(Transaction trackByTransaction, ManagedConnectionPool mcp,
+                                                  Subject subject, ConnectionRequestInfo cri)
+      throws ResourceException
+   {
+      // Need a new one for this transaction
+      // This must be done outside the tx local lock, otherwise
+      // the tx timeout won't work and get connection can do a lot of other work
+      // with many opportunities for deadlocks.
+      // Instead we do a double check after we got the transaction to see
+      // whether another thread beat us to the punch.
+      ConnectionListener cl = mcp.getConnection(subject, cri);
+      log.tracef("Got connection from pool tracked by transaction=%s tx=%s", cl, trackByTransaction);
+
+      if (cm.isEnlistment() && cl.supportsLazyEnlistment())
+      {
+         log.tracef("Lazy enlistment connection from pool tracked by transaction=%s tx=%s", cl, trackByTransaction);
+
+         return cl;
+      }
+
+      TransactionSynchronizationRegistry tsr = getTransactionSynchronizationRegistry();
+      Lock lock = getTSRLock();
+
+      if (lock == null)
+      {
+         if (cl != null)
+         {
+            log.tracef("Killing connection tracked by transaction=%s tx=%s", cl, trackByTransaction);
+
+            returnConnection(cl, true);
+         }
+
+         throw new ResourceException(bundle.unableObtainLock());
+      }
+
+      try
+      {
+         lock.lockInterruptibly();
+      }
+      catch (InterruptedException ie)
+      {
+         Thread.interrupted();
+
+         if (cl != null)
+         {
+            log.tracef("Killing connection tracked by transaction=%s tx=%s", cl, trackByTransaction);
+
+            returnConnection(cl, true);
+         }
+
+         throw new ResourceException(bundle.unableObtainLock(), ie);
+      }
+      try
+      {
+         // Check we weren't racing with another transaction
+         ConnectionListener other =
+            (ConnectionListener)tsr.getResource(mcp);
+
+         if (other != null)
+         {
+            returnConnection(cl, false);
+
+            log.tracef("Another thread already got a connection tracked by transaction=%s tx=%s",
+                       other, trackByTransaction);
+
+            cl = other;
+         }
+
+         // This is the connection for this transaction
+         cl.setTrackByTx(true);
+         tsr.putResource(mcp, cl);
+
+         log.tracef("Using connection from pool tracked by transaction=%s tx=%s", cl, trackByTransaction);
+
+         return cl;
+      }
+      catch (Throwable t)
+      {
+         if (cl != null)
+         {
+            log.tracef("Killing connection tracked by transaction=%s tx=%s", cl, trackByTransaction);
+
+            returnConnection(cl, true);
+         }
+
+         throw new ResourceException(bundle.unableGetConnectionListener(), t);
+      }
+      finally
+      {
+         lock.unlock();
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public ConnectionListener findConnectionListener(ManagedConnection mc)
+   {
+      return findConnectionListener(mc, null);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public ConnectionListener findConnectionListener(ManagedConnection mc, Object connection)
+   {
+      for (ManagedConnectionPool mcp : mcpPools.values())
+      {
+         ConnectionListener cl = mcp.findConnectionListener(mc, connection);
+         if (cl != null)
+            return cl;
+      }
+
+      return null;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public ManagedConnectionFactory getManagedConnectionFactory()
+   {
+      return mcf;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void returnConnection(ConnectionListener cl, boolean kill) throws ResourceException
+   {
+      cl.setTrackByTx(false);
+      //Get connection listener pool
+      ManagedConnectionPool mcp = cl.getManagedConnectionPool();
+
+      if (Tracer.isEnabled())
+      {
+         if (kill && cl.getException() != null)
+            Tracer.exception(poolName, cl.getManagedConnectionPool(), cl, cl.getException());
+
+         Tracer.returnConnectionListener(poolName, cl.getManagedConnectionPool(), cl, kill, interleaving,
+                                         Tracer.isRecordCallstacks() ? new Throwable("CALLSTACK") : null);
+      }
+
+      //Return connection to the pool
+      mcp.returnConnection(cl, kill);
+
+      log.tracef("Returning connection to pool %s", cl);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean hasConnection(Subject subject, ConnectionRequestInfo cri)
+   {
+      TransactionSynchronizationRegistry tsr = getTransactionSynchronizationRegistry();
+      Lock lock = getTSRLock();
+
+      if (lock == null)
+         return false;
+
+      try
+      {
+         lock.lockInterruptibly();
+      }
+      catch (InterruptedException ie)
+      {
+         Thread.interrupted();
+         return false;
+      }
+      try
+      {
+         boolean separateNoTx = false;
+
+         if (noTxSeparatePools)
+         {
+            separateNoTx = cm.isTransactional();
+         }
+
+         // Get specific managed connection pool key
+         Object key = getKey(subject, cri, separateNoTx);
+
+         // Get managed connection pool
+         ManagedConnectionPool mcp = getManagedConnectionPool(key, subject, cri);
+
+         // Already got one
+         ConnectionListener cl = (ConnectionListener)tsr.getResource(mcp);
+         if (cl != null)
+         {
+            return true;
+         }
+      }
+      catch (Throwable t)
+      {
+         log.debugf(t, "hasConnection error: %s", t.getMessage());
+      }
+      finally
+      {
+         lock.unlock();
+      }
+
+      return false;
+   }
+
+   /**
+    * Get the connection manager
+    * @return The value
+    */
+   protected ConnectionManager getConnectionManager()
+   {
+      return cm;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void setConnectionManager(ConnectionManager cm)
+   {
+      this.cm = cm;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean isShutdown()
+   {
+      return shutdown.get();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public synchronized void shutdown()
+   {
+      log.debugf("%s: shutdown", poolName);
+      shutdown.set(true);
+
+      Iterator it = mcpPools.values().iterator();
+      while (it.hasNext())
+      {
+         ManagedConnectionPool mcp = it.next();
+         try
+         {
+            mcp.shutdown();
+         }
+         catch (Exception e)
+         {
+            // Should not happen
+            log.tracef(e, "MCP.shutdown: %s", e.getMessage());
+         }
+
+         if (Tracer.isEnabled())
+            Tracer.destroyManagedConnectionPool(getName(), mcp);
+      }
+
+      mcpPools.clear();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void prepareShutdown()
+   {
+      log.debugf("%s: prepareShutdown", poolName);
+      shutdown.set(true);
+
+      flush(FlushMode.GRACEFULLY);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean cancelShutdown()
+   {
+      log.debugf("%s: cancelShutdown", poolName);
+
+      if (shutdown.get())
+      {
+         shutdown.set(false);
+         
+         if (isPrefill())
+         {
+            Iterator it = mcpPools.values().iterator();
+            while (it.hasNext())
+            {
+               ManagedConnectionPool mcp = it.next();
+               try
+               {
+                  mcp.prefill();
+               }
+               catch (Exception e)
+               {
+                  // Should not happen
+                  log.trace("MCP.prefill: " + e.getMessage(), e);
+               }
+            }
+         }
+
+         return true;
+      }
+      
+      return false;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public PoolStatistics getStatistics()
+   {
+      return statistics;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public PoolStatisticsImpl getInternalStatistics()
+   {
+      return statistics;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public abstract boolean testConnection();
+
+   /**
+    * {@inheritDoc}
+    */
+   public abstract boolean testConnection(ConnectionRequestInfo cri, Subject subject);
+
+   /**
+    * Test if a connection can be obtained
+    * @param subject Optional subject
+    * @param cri Optional CRI
+    * @return True if possible; otherwise false
+    */
+   protected boolean internalTestConnection(ConnectionRequestInfo cri, Subject subject)
+   {
+      log.debugf("%s: testConnection(%s, %s) (%s)", poolName, cri, subject,
+                 Integer.toHexString(System.identityHashCode(subject)));
+
+      log.debugf("%s:   Statistics=%s", poolName, statistics);
+
+      boolean result = false;
+      boolean kill = false;
+      ConnectionListener cl = null;
+
+      if (shutdown.get())
+         return false;
+
+      if (isFull())
+         return false;
+
+      try
+      {
+         boolean separateNoTx = false;
+
+         if (noTxSeparatePools)
+         {
+            separateNoTx = cm.isTransactional();
+         }
+
+         Object key = getKey(subject, cri, separateNoTx);
+         ManagedConnectionPool mcp = getManagedConnectionPool(key, subject, cri);
+
+         cl = mcp.getConnection(subject, cri);
+         result = true;
+      }
+      catch (Throwable t)
+      {
+         kill = true;
+      }
+      finally
+      {
+         if (cl != null)
+         {
+            try
+            {
+               returnConnection(cl, kill);
+            }
+            catch (ResourceException ire)
+            {
+               // Ignore
+            }
+         }
+      }
+
+      return result;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public String[] dumpQueuedThreads()
+   {
+      List result = new ArrayList();
+
+      if (permits.hasQueuedThreads())
+      {
+         Collection queuedThreads = new ArrayList(permits.getQueuedThreads());
+         for (Thread t : queuedThreads)
+         {
+            result.add(dumpQueuedThread(t));
+         }
+      }
+
+      return result.toArray(new String[result.size()]);
+   }
+
+   /**
+    * Dump a thread
+    * @param t The thread
+    * @return The stack trace
+    */
+   private String dumpQueuedThread(Thread t)
+   {
+      StringBuilder sb = new StringBuilder();
+
+      // Header
+      sb = sb.append("Queued thread: ");
+      sb = sb.append(t.getName());
+      sb = sb.append(newLine);
+
+      // Body
+      StackTraceElement[] stes = SecurityActions.getStackTrace(t);
+      if (stes != null)
+      {
+         for (StackTraceElement ste : stes)
+         {
+            sb = sb.append("  ");
+            sb = sb.append(ste.getClassName());
+            sb = sb.append(":");
+            sb = sb.append(ste.getMethodName());
+            sb = sb.append(":");
+            sb = sb.append(ste.getLineNumber());
+            sb = sb.append(newLine);
+         }
+      }
+
+      return sb.toString();
+   }
+
+   /**
+    * Get the managed connection pools. 
+    * @return The managed connection pools
+    */
+   protected ConcurrentMap getManagedConnectionPools()
+   {
+      return mcpPools;
+   }
+
+   /**
+    * Get the pool configuration
+    * @return The value
+    */
+   protected PoolConfiguration getPoolConfiguration()
+   {
+      return poolConfiguration;
+   }
+
+   /**
+    * Is prefill
+    * @return The value
+    */
+   protected boolean isPrefill()
+   {
+      return false;
+   }
+
+   /**
+    * Get the logger
+    * @return The value
+    */
+   public abstract CoreLogger getLogger();
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/AbstractPrefillPool.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/AbstractPrefillPool.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/AbstractPrefillPool.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,93 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2008-2009, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager.pool;
+
+import org.jboss.jca.core.api.connectionmanager.pool.PoolConfiguration;
+import org.jboss.jca.core.connectionmanager.pool.api.PrefillPool;
+
+import javax.resource.spi.ConnectionRequestInfo;
+import javax.resource.spi.ManagedConnectionFactory;
+import javax.security.auth.Subject;
+
+/**
+ * Abstract pool implementation which can be prefilled.
+ *
+ * @author Jesper Pedersen 
+ */
+public abstract class AbstractPrefillPool extends AbstractPool implements PrefillPool
+{
+   /** Should prefill be performed */
+   private boolean shouldPrefill = false;
+
+   /**
+    * Create a new prefill pool.
+    * 
+    * @param mcf the managed connection factory
+    * @param pc the pool configuration
+    * @param noTxSeparatePools noTxSeparatePool
+    * @param sharable Are the connections sharable
+    * @param mcp mcp
+    */
+   protected AbstractPrefillPool(final ManagedConnectionFactory mcf, final PoolConfiguration pc,
+                                 final boolean noTxSeparatePools, final boolean sharable, final String mcp)
+   {
+      super(mcf, pc, noTxSeparatePools, sharable, mcp);
+      this.shouldPrefill = pc.isPrefill() || pc.isStrictMin();
+   }
+
+   /**
+    * {@inheritDoc}
+    */   
+   public void prefill(Subject subject, ConnectionRequestInfo cri, boolean noTxnSeperatePool)
+   {
+      if (shouldPrefill)
+      {
+         if (log.isDebugEnabled())
+            log.debug("Attempting to prefill pool: " + getName());
+
+         try
+         {
+            //Get pool key
+            Object key = getKey(subject, cri, noTxnSeperatePool);
+            
+            //Get pool automatically initializes pool
+            getManagedConnectionPool(key, subject, cri);
+         }
+         catch (Throwable t)
+         {
+            //No real need to throw here being that pool remains in the same state as before.
+            log.error("Unable to prefill pool: " + getName(), t);
+         }
+      }
+   }
+
+   /**
+    * Is prefill
+    * @return The value
+    */
+   @Override
+   protected boolean isPrefill()
+   {
+      return getPoolConfiguration().getMinSize() > 0;
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/PoolStatisticsImpl.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/PoolStatisticsImpl.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/PoolStatisticsImpl.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,1752 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2011, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager.pool;
+
+import org.jboss.jca.core.api.connectionmanager.pool.PoolStatistics;
+import org.jboss.jca.core.spi.transaction.XAResourceStatistics;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.ResourceBundle;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * Pool statistics
+ *
+ * @author Jesper Pedersen 
+ */
+public class PoolStatisticsImpl implements PoolStatistics, XAResourceStatistics
+{
+   /** Serial version uid */
+   private static final long serialVersionUID = 9L;
+
+   private static final String ACTIVE_COUNT = "ActiveCount";
+   private static final String AVAILABLE_COUNT = "AvailableCount";
+   private static final String AVERAGE_BLOCKING_TIME = "AverageBlockingTime";
+   private static final String AVERAGE_CREATION_TIME = "AverageCreationTime";
+   private static final String AVERAGE_GET_TIME = "AverageGetTime";
+   private static final String AVERAGE_POOL_TIME = "AveragePoolTime";
+   private static final String AVERAGE_USAGE_TIME = "AverageUsageTime";
+   private static final String BLOCKING_FAILURE_COUNT = "BlockingFailureCount";
+   private static final String CREATED_COUNT = "CreatedCount";
+   private static final String DESTROYED_COUNT = "DestroyedCount";
+   private static final String IDLE_COUNT = "IdleCount";
+   private static final String IN_USE_COUNT = "InUseCount";
+   private static final String MAX_CREATION_TIME = "MaxCreationTime";
+   private static final String MAX_GET_TIME = "MaxGetTime";
+   private static final String MAX_POOL_TIME = "MaxPoolTime";
+   private static final String MAX_USAGE_TIME = "MaxUsageTime";
+   private static final String MAX_USED_COUNT = "MaxUsedCount";
+   private static final String MAX_WAIT_COUNT = "MaxWaitCount";
+   private static final String MAX_WAIT_TIME = "MaxWaitTime";
+   private static final String TIMED_OUT = "TimedOut";
+   private static final String TOTAL_BLOCKING_TIME = "TotalBlockingTime";
+   private static final String TOTAL_CREATION_TIME = "TotalCreationTime";
+   private static final String TOTAL_GET_TIME = "TotalGetTime";
+   private static final String TOTAL_POOL_TIME = "TotalPoolTime";
+   private static final String TOTAL_USAGE_TIME = "TotalUsageTime";
+   private static final String WAIT_COUNT = "WaitCount";
+
+   private static final String XA_COMMIT_COUNT = "XACommitCount";
+   private static final String XA_COMMIT_AVERAGE_TIME = "XACommitAverageTime";
+   private static final String XA_COMMIT_TOTAL_TIME = "XACommitTotalTime";
+   private static final String XA_COMMIT_MAX_TIME = "XACommitMaxTime";
+   private static final String XA_END_COUNT = "XAEndCount";
+   private static final String XA_END_AVERAGE_TIME = "XAEndAverageTime";
+   private static final String XA_END_TOTAL_TIME = "XAEndTotalTime";
+   private static final String XA_END_MAX_TIME = "XAEndMaxTime";
+   private static final String XA_FORGET_COUNT = "XAForgetCount";
+   private static final String XA_FORGET_AVERAGE_TIME = "XAForgetAverageTime";
+   private static final String XA_FORGET_TOTAL_TIME = "XAForgetTotalTime";
+   private static final String XA_FORGET_MAX_TIME = "XAForgetMaxTime";
+   private static final String XA_PREPARE_COUNT = "XAPrepareCount";
+   private static final String XA_PREPARE_AVERAGE_TIME = "XAPrepareAverageTime";
+   private static final String XA_PREPARE_TOTAL_TIME = "XAPrepareTotalTime";
+   private static final String XA_PREPARE_MAX_TIME = "XAPrepareMaxTime";
+   private static final String XA_RECOVER_COUNT = "XARecoverCount";
+   private static final String XA_RECOVER_AVERAGE_TIME = "XARecoverAverageTime";
+   private static final String XA_RECOVER_TOTAL_TIME = "XARecoverTotalTime";
+   private static final String XA_RECOVER_MAX_TIME = "XARecoverMaxTime";
+   private static final String XA_ROLLBACK_COUNT = "XARollbackCount";
+   private static final String XA_ROLLBACK_AVERAGE_TIME = "XARollbackAverageTime";
+   private static final String XA_ROLLBACK_TOTAL_TIME = "XARollbackTotalTime";
+   private static final String XA_ROLLBACK_MAX_TIME = "XARollbackMaxTime";
+   private static final String XA_START_COUNT = "XAStartCount";
+   private static final String XA_START_AVERAGE_TIME = "XAStartAverageTime";
+   private static final String XA_START_TOTAL_TIME = "XAStartTotalTime";
+   private static final String XA_START_MAX_TIME = "XAStartMaxTime";
+
+   private int maxPoolSize;
+   private transient SortedSet names;
+   private transient Map types;
+   private transient Map rbs;
+
+   private transient AtomicBoolean enabled;
+   private transient AtomicInteger createdCount;
+   private transient AtomicInteger destroyedCount;
+   private transient AtomicInteger maxUsedCount;
+   private transient AtomicLong maxCreationTime;
+   private transient AtomicLong maxGetTime;
+   private transient AtomicLong maxPoolTime;
+   private transient AtomicLong maxUsageTime;
+   private transient AtomicInteger maxWaitCount;
+   private transient AtomicLong maxWaitTime;
+   private transient AtomicInteger timedOut;
+   private transient AtomicLong totalBlockingTime;
+   private transient AtomicLong totalBlockingTimeInvocations;
+   private transient AtomicLong totalCreationTime;
+   private transient AtomicLong totalGetTime;
+   private transient AtomicLong totalGetTimeInvocations;
+   private transient AtomicLong totalPoolTime;
+   private transient AtomicLong totalPoolTimeInvocations;
+   private transient AtomicLong totalUsageTime;
+   private transient AtomicLong totalUsageTimeInvocations;
+   private transient AtomicInteger inUseCount;
+   private transient AtomicInteger blockingFailureCount;
+   private transient AtomicInteger waitCount;
+
+
+   private transient AtomicLong commitCount;
+   private transient AtomicLong commitTotalTime;
+   private transient AtomicLong commitMaxTime;
+   private transient AtomicLong endCount;
+   private transient AtomicLong endTotalTime;
+   private transient AtomicLong endMaxTime;
+   private transient AtomicLong forgetCount;
+   private transient AtomicLong forgetTotalTime;
+   private transient AtomicLong forgetMaxTime;
+   private transient AtomicLong prepareCount;
+   private transient AtomicLong prepareTotalTime;
+   private transient AtomicLong prepareMaxTime;
+   private transient AtomicLong recoverCount;
+   private transient AtomicLong recoverTotalTime;
+   private transient AtomicLong recoverMaxTime;
+   private transient AtomicLong rollbackCount;
+   private transient AtomicLong rollbackTotalTime;
+   private transient AtomicLong rollbackMaxTime;
+   private transient AtomicLong startCount;
+   private transient AtomicLong startTotalTime;
+   private transient AtomicLong startMaxTime;
+
+   /**
+    * Constructor
+    * @param maxPoolSize The maximum pool size
+    */
+   public PoolStatisticsImpl(int maxPoolSize)
+   {
+      init(maxPoolSize);
+   }
+
+   /**
+    * Init
+    * @param maxPoolSize The maximum pool size
+    */
+   private void init(int maxPoolSize)
+   {
+      this.maxPoolSize = maxPoolSize;
+
+      this.createdCount = new AtomicInteger(0);
+      this.destroyedCount = new AtomicInteger(0);
+      this.maxCreationTime = new AtomicLong(Long.MIN_VALUE);
+      this.maxGetTime = new AtomicLong(Long.MIN_VALUE);
+      this.maxPoolTime = new AtomicLong(Long.MIN_VALUE);
+      this.maxUsageTime = new AtomicLong(Long.MIN_VALUE);
+      this.maxUsedCount = new AtomicInteger(Integer.MIN_VALUE);
+      this.maxWaitCount = new AtomicInteger(0);
+      this.maxWaitTime = new AtomicLong(Long.MIN_VALUE);
+      this.timedOut = new AtomicInteger(0);
+      this.totalBlockingTime = new AtomicLong(0);
+      this.totalBlockingTimeInvocations = new AtomicLong(0);
+      this.totalCreationTime = new AtomicLong(0);
+      this.totalGetTime = new AtomicLong(0);
+      this.totalGetTimeInvocations = new AtomicLong(0);
+      this.totalPoolTime = new AtomicLong(0);
+      this.totalPoolTimeInvocations = new AtomicLong(0);
+      this.totalUsageTime = new AtomicLong(0);
+      this.totalUsageTimeInvocations = new AtomicLong(0);
+      this.inUseCount = new AtomicInteger(0);
+      this.blockingFailureCount = new AtomicInteger(0);
+      this.waitCount = new AtomicInteger(0);
+
+      this.commitCount = new AtomicLong(0L);
+      this.commitTotalTime = new AtomicLong(0L);
+      this.commitMaxTime = new AtomicLong(0L);
+      this.endCount = new AtomicLong(0L);
+      this.endTotalTime = new AtomicLong(0L);
+      this.endMaxTime = new AtomicLong(0L);
+      this.forgetCount = new AtomicLong(0L);
+      this.forgetTotalTime = new AtomicLong(0L);
+      this.forgetMaxTime = new AtomicLong(0L);
+      this.prepareCount = new AtomicLong(0L);
+      this.prepareTotalTime = new AtomicLong(0L);
+      this.prepareMaxTime = new AtomicLong(0L);
+      this.recoverCount = new AtomicLong(0L);
+      this.recoverTotalTime = new AtomicLong(0L);
+      this.recoverMaxTime = new AtomicLong(0L);
+      this.rollbackCount = new AtomicLong(0L);
+      this.rollbackTotalTime = new AtomicLong(0L);
+      this.rollbackMaxTime = new AtomicLong(0L);
+      this.startCount = new AtomicLong(0L);
+      this.startTotalTime = new AtomicLong(0L);
+      this.startMaxTime = new AtomicLong(0L);
+
+      SortedSet n = new TreeSet();
+      Map t = new HashMap();
+
+      n.add(ACTIVE_COUNT);
+      t.put(ACTIVE_COUNT, int.class);
+
+      n.add(AVAILABLE_COUNT);
+      t.put(AVAILABLE_COUNT, int.class);
+
+      n.add(AVERAGE_BLOCKING_TIME);
+      t.put(AVERAGE_BLOCKING_TIME, long.class);
+
+      n.add(AVERAGE_CREATION_TIME);
+      t.put(AVERAGE_CREATION_TIME, long.class);
+
+      n.add(AVERAGE_GET_TIME);
+      t.put(AVERAGE_GET_TIME, long.class);
+
+      n.add(AVERAGE_USAGE_TIME);
+      t.put(AVERAGE_USAGE_TIME, long.class);
+
+      n.add(AVERAGE_POOL_TIME);
+      t.put(AVERAGE_POOL_TIME, long.class);
+
+      n.add(BLOCKING_FAILURE_COUNT);
+      t.put(BLOCKING_FAILURE_COUNT, int.class);
+
+      n.add(CREATED_COUNT);
+      t.put(CREATED_COUNT, int.class);
+
+      n.add(DESTROYED_COUNT);
+      t.put(DESTROYED_COUNT, int.class);
+
+      n.add(IDLE_COUNT);
+      t.put(IDLE_COUNT, int.class);
+
+      n.add(IN_USE_COUNT);
+      t.put(IN_USE_COUNT, int.class);
+
+      n.add(MAX_CREATION_TIME);
+      t.put(MAX_CREATION_TIME, long.class);
+
+      n.add(MAX_GET_TIME);
+      t.put(MAX_GET_TIME, long.class);
+
+      n.add(MAX_POOL_TIME);
+      t.put(MAX_POOL_TIME, long.class);
+
+      n.add(MAX_USAGE_TIME);
+      t.put(MAX_USAGE_TIME, long.class);
+
+      n.add(MAX_USED_COUNT);
+      t.put(MAX_USED_COUNT, int.class);
+
+      n.add(MAX_WAIT_COUNT);
+      t.put(MAX_WAIT_COUNT, int.class);
+
+      n.add(MAX_WAIT_TIME);
+      t.put(MAX_WAIT_TIME, long.class);
+
+      n.add(TIMED_OUT);
+      t.put(TIMED_OUT, int.class);
+
+      n.add(TOTAL_BLOCKING_TIME);
+      t.put(TOTAL_BLOCKING_TIME, long.class);
+
+      n.add(TOTAL_CREATION_TIME);
+      t.put(TOTAL_CREATION_TIME, long.class);
+
+      n.add(TOTAL_GET_TIME);
+      t.put(TOTAL_GET_TIME, long.class);
+
+      n.add(TOTAL_POOL_TIME);
+      t.put(TOTAL_POOL_TIME, long.class);
+
+      n.add(TOTAL_USAGE_TIME);
+      t.put(TOTAL_USAGE_TIME, long.class);
+
+      n.add(WAIT_COUNT);
+      t.put(WAIT_COUNT, int.class);
+
+      n.add(XA_COMMIT_COUNT);
+      t.put(XA_COMMIT_COUNT, long.class);
+      n.add(XA_COMMIT_AVERAGE_TIME);
+      t.put(XA_COMMIT_AVERAGE_TIME, long.class);
+      n.add(XA_COMMIT_TOTAL_TIME);
+      t.put(XA_COMMIT_TOTAL_TIME, long.class);
+      n.add(XA_COMMIT_MAX_TIME);
+      t.put(XA_COMMIT_MAX_TIME, long.class);
+
+      n.add(XA_END_COUNT);
+      t.put(XA_END_COUNT, long.class);
+      n.add(XA_END_AVERAGE_TIME);
+      t.put(XA_END_AVERAGE_TIME, long.class);
+      n.add(XA_END_TOTAL_TIME);
+      t.put(XA_END_TOTAL_TIME, long.class);
+      n.add(XA_END_MAX_TIME);
+      t.put(XA_END_MAX_TIME, long.class);
+
+      n.add(XA_FORGET_COUNT);
+      t.put(XA_FORGET_COUNT, long.class);
+      n.add(XA_FORGET_AVERAGE_TIME);
+      t.put(XA_FORGET_AVERAGE_TIME, long.class);
+      n.add(XA_FORGET_TOTAL_TIME);
+      t.put(XA_FORGET_TOTAL_TIME, long.class);
+      n.add(XA_FORGET_MAX_TIME);
+      t.put(XA_FORGET_MAX_TIME, long.class);
+
+      n.add(XA_PREPARE_COUNT);
+      t.put(XA_PREPARE_COUNT, long.class);
+      n.add(XA_PREPARE_AVERAGE_TIME);
+      t.put(XA_PREPARE_AVERAGE_TIME, long.class);
+      n.add(XA_PREPARE_TOTAL_TIME);
+      t.put(XA_PREPARE_TOTAL_TIME, long.class);
+      n.add(XA_PREPARE_MAX_TIME);
+      t.put(XA_PREPARE_MAX_TIME, long.class);
+
+      n.add(XA_RECOVER_COUNT);
+      t.put(XA_RECOVER_COUNT, long.class);
+      n.add(XA_RECOVER_AVERAGE_TIME);
+      t.put(XA_RECOVER_AVERAGE_TIME, long.class);
+      n.add(XA_RECOVER_TOTAL_TIME);
+      t.put(XA_RECOVER_TOTAL_TIME, long.class);
+      n.add(XA_RECOVER_MAX_TIME);
+      t.put(XA_RECOVER_MAX_TIME, long.class);
+
+      n.add(XA_ROLLBACK_COUNT);
+      t.put(XA_ROLLBACK_COUNT, long.class);
+      n.add(XA_ROLLBACK_AVERAGE_TIME);
+      t.put(XA_ROLLBACK_AVERAGE_TIME, long.class);
+      n.add(XA_ROLLBACK_TOTAL_TIME);
+      t.put(XA_ROLLBACK_TOTAL_TIME, long.class);
+      n.add(XA_ROLLBACK_MAX_TIME);
+      t.put(XA_ROLLBACK_MAX_TIME, long.class);
+
+      n.add(XA_START_COUNT);
+      t.put(XA_START_COUNT, long.class);
+      n.add(XA_START_AVERAGE_TIME);
+      t.put(XA_START_AVERAGE_TIME, long.class);
+      n.add(XA_START_TOTAL_TIME);
+      t.put(XA_START_TOTAL_TIME, long.class);
+      n.add(XA_START_MAX_TIME);
+      t.put(XA_START_MAX_TIME, long.class);
+
+      this.names = Collections.unmodifiableSortedSet(n);
+      this.types = Collections.unmodifiableMap(t);
+      this.enabled = new AtomicBoolean(true);
+      
+      ResourceBundle defaultResourceBundle = 
+         ResourceBundle.getBundle("poolstatistics", Locale.US,
+                                  SecurityActions.getClassLoader(PoolStatisticsImpl.class));
+      this.rbs = new HashMap(1);
+      this.rbs.put(Locale.US, defaultResourceBundle);
+
+      clear();
+   }
+
+
+   /**
+    * {@inheritDoc}
+    */
+   public Set getNames()
+   {
+      return names;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public Class getType(String name)
+   {
+      return types.get(name);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public String getDescription(String name)
+   {
+      return getDescription(name, Locale.US);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public String getDescription(String name, Locale locale)
+   {
+      ResourceBundle rb = rbs.get(locale);
+
+      if (rb == null)
+      {
+         ResourceBundle newResourceBundle =
+            ResourceBundle.getBundle("poolstatistics", locale,
+                                     SecurityActions.getClassLoader(PoolStatisticsImpl.class));
+
+         if (newResourceBundle != null)
+            rbs.put(locale, newResourceBundle);
+      }
+
+      if (rb == null)
+         rb = rbs.get(Locale.US);
+
+      if (rb != null)
+         return rb.getString(name);
+
+      return "";
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public Object getValue(String name)
+   {
+      if (ACTIVE_COUNT.equals(name))
+      {
+         return getActiveCount();
+      }
+      else if (AVAILABLE_COUNT.equals(name))
+      {
+         return getAvailableCount();
+      }
+      else if (AVERAGE_BLOCKING_TIME.equals(name))
+      {
+         return getAverageBlockingTime();
+      }
+      else if (AVERAGE_CREATION_TIME.equals(name))
+      {
+         return getAverageCreationTime();
+      }
+      else if (AVERAGE_GET_TIME.equals(name))
+      {
+         return getAverageGetTime();
+      }
+      else if (AVERAGE_USAGE_TIME.equals(name))
+      {
+         return getAverageUsageTime();
+      }
+      else if (AVERAGE_POOL_TIME.equals(name))
+      {
+         return getAveragePoolTime();
+      }
+      else if (BLOCKING_FAILURE_COUNT.equals(name))
+      {
+         return getBlockingFailureCount();
+      }
+      else if (CREATED_COUNT.equals(name))
+      {
+         return getCreatedCount();
+      }
+      else if (DESTROYED_COUNT.equals(name))
+      {
+         return getDestroyedCount();
+      }
+      else if (IDLE_COUNT.equals(name))
+      {
+         return getIdleCount();
+      }
+      else if (IN_USE_COUNT.equals(name))
+      {
+         return getInUseCount();
+      }
+      else if (MAX_CREATION_TIME.equals(name))
+      {
+         return getMaxCreationTime();
+      }
+      else if (MAX_GET_TIME.equals(name))
+      {
+         return getMaxGetTime();
+      }
+      else if (MAX_POOL_TIME.equals(name))
+      {
+         return getMaxPoolTime();
+      }
+      else if (MAX_USAGE_TIME.equals(name))
+      {
+         return getMaxUsageTime();
+      }
+      else if (MAX_USED_COUNT.equals(name))
+      {
+         return getMaxUsedCount();
+      }
+      else if (MAX_WAIT_COUNT.equals(name))
+      {
+         return getMaxWaitCount();
+      }
+      else if (MAX_WAIT_TIME.equals(name))
+      {
+         return getMaxWaitTime();
+      }
+      else if (TIMED_OUT.equals(name))
+      {
+         return getTimedOut();
+      }
+      else if (TOTAL_BLOCKING_TIME.equals(name))
+      {
+         return getTotalBlockingTime();
+      }
+      else if (TOTAL_CREATION_TIME.equals(name))
+      {
+         return getTotalCreationTime();
+      }
+      else if (TOTAL_GET_TIME.equals(name))
+      {
+         return getTotalGetTime();
+      }
+      else if (TOTAL_POOL_TIME.equals(name))
+      {
+         return getTotalPoolTime();
+      }
+      else if (TOTAL_USAGE_TIME.equals(name))
+      {
+         return getTotalUsageTime();
+      }
+      else if (WAIT_COUNT.equals(name))
+      {
+         return getWaitCount();
+      }
+      else if (XA_COMMIT_COUNT.equals(name))
+      {
+         return getCommitCount();
+      }
+      else if (XA_COMMIT_AVERAGE_TIME.equals(name))
+      {
+         return getCommitAverageTime();
+      }
+      else if (XA_COMMIT_TOTAL_TIME.equals(name))
+      {
+         return getCommitTotalTime();
+      }
+      else if (XA_COMMIT_MAX_TIME.equals(name))
+      {
+         return getCommitMaxTime();
+      }
+      else if (XA_END_COUNT.equals(name))
+      {
+         return getEndCount();
+      }
+      else if (XA_END_AVERAGE_TIME.equals(name))
+      {
+         return getEndAverageTime();
+      }
+      else if (XA_END_TOTAL_TIME.equals(name))
+      {
+         return getEndTotalTime();
+      }
+      else if (XA_END_MAX_TIME.equals(name))
+      {
+         return getEndMaxTime();
+      }
+      else if (XA_FORGET_COUNT.equals(name))
+      {
+         return getForgetCount();
+      }
+      else if (XA_FORGET_AVERAGE_TIME.equals(name))
+      {
+         return getForgetAverageTime();
+      }
+      else if (XA_FORGET_TOTAL_TIME.equals(name))
+      {
+         return getForgetTotalTime();
+      }
+      else if (XA_FORGET_MAX_TIME.equals(name))
+      {
+         return getForgetMaxTime();
+      }
+      else if (XA_PREPARE_COUNT.equals(name))
+      {
+         return getPrepareCount();
+      }
+      else if (XA_PREPARE_AVERAGE_TIME.equals(name))
+      {
+         return getPrepareAverageTime();
+      }
+      else if (XA_PREPARE_TOTAL_TIME.equals(name))
+      {
+         return getPrepareTotalTime();
+      }
+      else if (XA_PREPARE_MAX_TIME.equals(name))
+      {
+         return getPrepareMaxTime();
+      }
+      else if (XA_RECOVER_COUNT.equals(name))
+      {
+         return getRecoverCount();
+      }
+      else if (XA_RECOVER_AVERAGE_TIME.equals(name))
+      {
+         return getRecoverAverageTime();
+      }
+      else if (XA_RECOVER_TOTAL_TIME.equals(name))
+      {
+         return getRecoverTotalTime();
+      }
+      else if (XA_RECOVER_MAX_TIME.equals(name))
+      {
+         return getRecoverMaxTime();
+      }
+      else if (XA_ROLLBACK_COUNT.equals(name))
+      {
+         return getRollbackCount();
+      }
+      else if (XA_ROLLBACK_AVERAGE_TIME.equals(name))
+      {
+         return getRollbackAverageTime();
+      }
+      else if (XA_ROLLBACK_TOTAL_TIME.equals(name))
+      {
+         return getRollbackTotalTime();
+      }
+      else if (XA_ROLLBACK_MAX_TIME.equals(name))
+      {
+         return getRollbackMaxTime();
+      }
+      else if (XA_START_COUNT.equals(name))
+      {
+         return getStartCount();
+      }
+      else if (XA_START_AVERAGE_TIME.equals(name))
+      {
+         return getStartAverageTime();
+      }
+      else if (XA_START_TOTAL_TIME.equals(name))
+      {
+         return getStartTotalTime();
+      }
+      else if (XA_START_MAX_TIME.equals(name))
+      {
+         return getStartMaxTime();
+      }
+
+      return null;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean isEnabled()
+   {
+      return enabled.get();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void setEnabled(boolean v)
+   {
+      if (enabled.get() != v)
+      {
+         enabled.set(v);
+         clear();
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public int getActiveCount()
+   {
+      if (!enabled.get())
+         return 0;
+
+      if (createdCount.get() < destroyedCount.get())
+         clear();
+
+      return createdCount.get() - destroyedCount.get();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public int getAvailableCount()
+   {
+      if (!enabled.get())
+         return 0;
+
+      return maxPoolSize - inUseCount.get();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getAverageBlockingTime()
+   {
+      if (!enabled.get())
+         return 0L;
+
+      return totalBlockingTimeInvocations.get() != 0 ? totalBlockingTime.get() / totalBlockingTimeInvocations.get() : 0;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getAverageCreationTime()
+   {
+      if (!enabled.get())
+         return 0L;
+
+      return createdCount.get() != 0 ? totalCreationTime.get() / createdCount.get() : 0;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getAverageGetTime()
+   {
+      if (!enabled.get())
+         return 0L;
+
+      return totalGetTimeInvocations.get() != 0 ? totalGetTime.get() / totalGetTimeInvocations.get() : 0;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getAverageUsageTime()
+   {
+      if (!enabled.get())
+         return 0L;
+
+      return totalUsageTimeInvocations.get() != 0 ? totalUsageTime.get() / totalUsageTimeInvocations.get() : 0;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getAveragePoolTime()
+   {
+      if (!enabled.get())
+         return 0L;
+
+      return totalPoolTimeInvocations.get() != 0 ? totalPoolTime.get() / totalPoolTimeInvocations.get() : 0;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public int getBlockingFailureCount()
+   {
+      if (!enabled.get())
+         return 0;
+
+      return blockingFailureCount.get();
+   }
+
+   /**
+    * Delta the blocking failure count value
+    */
+   public void deltaBlockingFailureCount()
+   {
+      if (enabled.get())
+         blockingFailureCount.incrementAndGet();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public int getCreatedCount()
+   {
+      if (!enabled.get())
+         return 0;
+
+      return createdCount.get();
+   }
+
+   /**
+    * Delta the created count value
+    */
+   public void deltaCreatedCount()
+   {
+      if (enabled.get())
+         createdCount.incrementAndGet();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public int getDestroyedCount()
+   {
+      if (!enabled.get())
+         return 0;
+
+      return destroyedCount.get();
+   }
+
+   /**
+    * Delta the destroyed count value
+    */
+   public void deltaDestroyedCount()
+   {
+      if (enabled.get())
+         destroyedCount.incrementAndGet();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public int getIdleCount()
+   {
+      if (!enabled.get())
+         return 0;
+
+      return getActiveCount() - getInUseCount();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public int getInUseCount()
+   {
+      if (!enabled.get())
+         return 0;
+
+      return inUseCount.get();
+   }
+
+   /**
+    * Set in used count
+    * @param v The value
+    */
+   public void setInUsedCount(int v)
+   {
+      inUseCount.set(v);
+      setMaxUsedCount(v);
+   }
+
+   /**
+    * Get max used count
+    * @return The value
+    */
+   public int getMaxUsedCount()
+   {
+      if (!enabled.get())
+         return 0;
+
+      return maxUsedCount.get() != Integer.MIN_VALUE ? maxUsedCount.get() : 0;
+   }
+
+   /**
+    * Set max used count
+    * @param v The value
+    */
+   private void setMaxUsedCount(int v)
+   {
+      if (v > maxUsedCount.get())
+         maxUsedCount.set(v);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getMaxCreationTime()
+   {
+      if (!enabled.get())
+         return 0L;
+
+      return maxCreationTime.get() != Long.MIN_VALUE ? maxCreationTime.get() : 0;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getMaxGetTime()
+   {
+      if (!enabled.get())
+         return 0L;
+
+      return maxGetTime.get() != Long.MIN_VALUE ? maxGetTime.get() : 0;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getMaxPoolTime()
+   {
+      if (!enabled.get())
+         return 0L;
+
+      return maxPoolTime.get() != Long.MIN_VALUE ? maxPoolTime.get() : 0;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getMaxUsageTime()
+   {
+      if (!enabled.get())
+         return 0L;
+
+      return maxUsageTime.get() != Long.MIN_VALUE ? maxUsageTime.get() : 0;
+   }
+
+   /**
+    * Get max wait count
+    * @return The value
+    */
+   public int getMaxWaitCount()
+   {
+      if (!isEnabled())
+         return 0;
+
+      return maxWaitCount.get() != Integer.MIN_VALUE ? maxWaitCount.get() : 0;
+   }
+
+   /**
+    * Set max wait count
+    * @param v The value
+    */
+   public void setMaxWaitCount(int v)
+   {
+      if (v > maxWaitCount.get())
+         maxWaitCount.set(v);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getMaxWaitTime()
+   {
+      if (!enabled.get())
+         return 0L;
+
+      return maxWaitTime.get() != Long.MIN_VALUE ? maxWaitTime.get() : 0;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public int getTimedOut()
+   {
+      if (!enabled.get())
+         return 0;
+
+      return timedOut.get();
+   }
+
+   /**
+    * Delta the timed out value
+    */
+   public void deltaTimedOut()
+   {
+      if (enabled.get())
+         timedOut.incrementAndGet();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getTotalBlockingTime()
+   {
+      if (!enabled.get())
+         return 0L;
+
+      return totalBlockingTime.get();
+   }
+
+   /**
+    * Add delta to total blocking timeout
+    * @param delta The value
+    */
+   public void deltaTotalBlockingTime(long delta)
+   {
+      if (enabled.get() && delta > 0)
+      {
+         totalBlockingTime.addAndGet(delta);
+         totalBlockingTimeInvocations.incrementAndGet();
+
+         if (delta > maxWaitTime.get())
+            maxWaitTime.set(delta);
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getTotalCreationTime()
+   {
+      if (!enabled.get())
+         return 0L;
+
+      return totalCreationTime.get();
+   }
+
+   /**
+    * Add delta to total creation time
+    * @param delta The value
+    */
+   public void deltaTotalCreationTime(long delta)
+   {
+      if (enabled.get() && delta > 0)
+      {
+         totalCreationTime.addAndGet(delta);
+
+         if (delta > maxCreationTime.get())
+            maxCreationTime.set(delta);
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getTotalGetTime()
+   {
+      if (!enabled.get())
+         return 0L;
+
+      return totalGetTime.get();
+   }
+
+   /**
+    * Add delta to total get time
+    * @param delta The value
+    */
+   public void deltaTotalGetTime(long delta)
+   {
+      if (enabled.get() && delta > 0)
+      {
+         totalGetTime.addAndGet(delta);
+         totalGetTimeInvocations.incrementAndGet();
+
+         if (delta > maxGetTime.get())
+            maxGetTime.set(delta);
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getTotalPoolTime()
+   {
+      if (!enabled.get())
+         return 0L;
+
+      return totalPoolTime.get();
+   }
+
+   /**
+    * Add delta to total pool time
+    * @param delta The value
+    */
+   public void deltaTotalPoolTime(long delta)
+   {
+      if (enabled.get() && delta > 0)
+      {
+         totalPoolTime.addAndGet(delta);
+         totalPoolTimeInvocations.incrementAndGet();
+
+         if (delta > maxPoolTime.get())
+            maxPoolTime.set(delta);
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getTotalUsageTime()
+   {
+      if (!enabled.get())
+         return 0L;
+
+      return totalUsageTime.get();
+   }
+
+   /**
+    * Add delta to total usage time
+    * @param delta The value
+    */
+   public void deltaTotalUsageTime(long delta)
+   {
+      if (enabled.get() && delta > 0)
+      {
+         totalUsageTime.addAndGet(delta);
+         totalUsageTimeInvocations.incrementAndGet();
+
+         if (delta > maxUsageTime.get())
+            maxUsageTime.set(delta);
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public int getWaitCount()
+   {
+      if (!enabled.get())
+         return 0;
+
+      return waitCount.get();
+   }
+
+   /**
+    * Add delta wait count
+    */
+   public void deltaWaitCount()
+   {
+      if (enabled.get())
+         waitCount.incrementAndGet();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getCommitCount()
+   {
+      if (!isEnabled())
+         return 0L;
+
+      return commitCount.get();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getCommitTotalTime()
+   {
+      if (!isEnabled())
+         return 0L;
+
+      return commitTotalTime.get();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getCommitAverageTime()
+   {
+      if (!isEnabled())
+         return 0L;
+
+      if (commitCount.get() > 0)
+         return commitTotalTime.get() / commitCount.get();
+
+      return 0L;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getCommitMaxTime()
+   {
+      if (!isEnabled())
+         return 0L;
+
+      return commitMaxTime.get();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void deltaCommit(long time)
+   {
+      commitCount.incrementAndGet();
+
+      if (time > 0)
+      {
+         commitTotalTime.addAndGet(time);
+
+         if (time > commitMaxTime.get())
+            commitMaxTime.set(time);
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getEndCount()
+   {
+      if (!isEnabled())
+         return 0L;
+
+      return endCount.get();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getEndTotalTime()
+   {
+      if (!isEnabled())
+         return 0L;
+
+      return endTotalTime.get();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getEndAverageTime()
+   {
+      if (!isEnabled())
+         return 0L;
+
+      if (endCount.get() > 0)
+         return endTotalTime.get() / endCount.get();
+
+      return 0L;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getEndMaxTime()
+   {
+      if (!isEnabled())
+         return 0L;
+
+      return endMaxTime.get();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void deltaEnd(long time)
+   {
+      endCount.incrementAndGet();
+
+      if (time > 0)
+      {
+         endTotalTime.addAndGet(time);
+
+         if (time > endMaxTime.get())
+            endMaxTime.set(time);
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getForgetCount()
+   {
+      if (!isEnabled())
+         return 0L;
+
+      return forgetCount.get();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getForgetTotalTime()
+   {
+      if (!isEnabled())
+         return 0L;
+
+      return forgetTotalTime.get();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getForgetAverageTime()
+   {
+      if (!isEnabled())
+         return 0L;
+
+      if (forgetCount.get() > 0)
+         return forgetTotalTime.get() / forgetCount.get();
+
+      return 0L;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getForgetMaxTime()
+   {
+      if (!isEnabled())
+         return 0L;
+
+      return forgetMaxTime.get();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void deltaForget(long time)
+   {
+      forgetCount.incrementAndGet();
+
+      if (time > 0)
+      {
+         forgetTotalTime.addAndGet(time);
+
+         if (time > forgetMaxTime.get())
+            forgetMaxTime.set(time);
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getPrepareCount()
+   {
+      if (!isEnabled())
+         return 0L;
+
+      return prepareCount.get();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getPrepareTotalTime()
+   {
+      if (!isEnabled())
+         return 0L;
+
+      return prepareTotalTime.get();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getPrepareAverageTime()
+   {
+      if (!isEnabled())
+         return 0L;
+
+      if (prepareCount.get() > 0)
+         return prepareTotalTime.get() / prepareCount.get();
+
+      return 0L;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getPrepareMaxTime()
+   {
+      if (!isEnabled())
+         return 0L;
+
+      return prepareMaxTime.get();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void deltaPrepare(long time)
+   {
+      prepareCount.incrementAndGet();
+
+      if (time > 0)
+      {
+         prepareTotalTime.addAndGet(time);
+
+         if (time > prepareMaxTime.get())
+            prepareMaxTime.set(time);
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getRecoverCount()
+   {
+      if (!isEnabled())
+         return 0L;
+
+      return recoverCount.get();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getRecoverTotalTime()
+   {
+      if (!isEnabled())
+         return 0L;
+
+      return recoverTotalTime.get();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getRecoverAverageTime()
+   {
+      if (!isEnabled())
+         return 0L;
+
+      if (recoverCount.get() > 0)
+         return recoverTotalTime.get() / recoverCount.get();
+
+      return 0L;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getRecoverMaxTime()
+   {
+      if (!isEnabled())
+         return 0L;
+
+      return recoverMaxTime.get();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void deltaRecover(long time)
+   {
+      recoverCount.incrementAndGet();
+
+      if (time > 0)
+      {
+         recoverTotalTime.addAndGet(time);
+
+         if (time > recoverMaxTime.get())
+            recoverMaxTime.set(time);
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getRollbackCount()
+   {
+      if (!isEnabled())
+         return 0L;
+
+      return rollbackCount.get();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getRollbackTotalTime()
+   {
+      if (!isEnabled())
+         return 0L;
+
+      return rollbackTotalTime.get();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getRollbackAverageTime()
+   {
+      if (!isEnabled())
+         return 0L;
+
+      if (rollbackCount.get() > 0)
+         return rollbackTotalTime.get() / rollbackCount.get();
+
+      return 0L;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getRollbackMaxTime()
+   {
+      if (!isEnabled())
+         return 0L;
+
+      return rollbackMaxTime.get();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void deltaRollback(long time)
+   {
+      rollbackCount.incrementAndGet();
+
+      if (time > 0)
+      {
+         rollbackTotalTime.addAndGet(time);
+
+         if (time > rollbackMaxTime.get())
+            rollbackMaxTime.set(time);
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getStartCount()
+   {
+      if (!isEnabled())
+         return 0L;
+
+      return startCount.get();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getStartTotalTime()
+   {
+      if (!isEnabled())
+         return 0L;
+
+      return startTotalTime.get();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getStartAverageTime()
+   {
+      if (!isEnabled())
+         return 0L;
+
+      if (startCount.get() > 0)
+         return startTotalTime.get() / startCount.get();
+
+      return 0L;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getStartMaxTime()
+   {
+      if (!isEnabled())
+         return 0L;
+
+      return startMaxTime.get();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void deltaStart(long time)
+   {
+      startCount.incrementAndGet();
+
+      if (time > 0)
+      {
+         startTotalTime.addAndGet(time);
+
+         if (time > startMaxTime.get())
+            startMaxTime.set(time);
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void clear()
+   {
+      this.createdCount.set(0);
+      this.destroyedCount.set(0);
+      this.maxCreationTime.set(Long.MIN_VALUE);
+      this.maxGetTime.set(Long.MIN_VALUE);
+      this.maxPoolTime.set(Long.MIN_VALUE);
+      this.maxUsageTime.set(Long.MIN_VALUE);
+      this.maxUsedCount.set(Integer.MIN_VALUE);
+      this.maxWaitTime.set(Long.MIN_VALUE);
+      this.timedOut.set(0);
+      this.totalBlockingTime.set(0L);
+      this.totalBlockingTimeInvocations.set(0L);
+      this.totalCreationTime.set(0L);
+      this.totalGetTime.set(0L);
+      this.totalGetTimeInvocations.set(0L);
+      this.totalPoolTime.set(0L);
+      this.totalPoolTimeInvocations.set(0L);
+      this.totalUsageTime.set(0L);
+      this.totalUsageTimeInvocations.set(0L);
+      this.inUseCount.set(0);
+      this.blockingFailureCount.set(0);
+      this.waitCount.set(0);
+
+      this.commitCount = new AtomicLong(0L);
+      this.commitTotalTime = new AtomicLong(0L);
+      this.commitMaxTime = new AtomicLong(0L);
+      this.endCount = new AtomicLong(0L);
+      this.endTotalTime = new AtomicLong(0L);
+      this.endMaxTime = new AtomicLong(0L);
+      this.forgetCount = new AtomicLong(0L);
+      this.forgetTotalTime = new AtomicLong(0L);
+      this.forgetMaxTime = new AtomicLong(0L);
+      this.prepareCount = new AtomicLong(0L);
+      this.prepareTotalTime = new AtomicLong(0L);
+      this.prepareMaxTime = new AtomicLong(0L);
+      this.recoverCount = new AtomicLong(0L);
+      this.recoverTotalTime = new AtomicLong(0L);
+      this.recoverMaxTime = new AtomicLong(0L);
+      this.rollbackCount = new AtomicLong(0L);
+      this.rollbackTotalTime = new AtomicLong(0L);
+      this.rollbackMaxTime = new AtomicLong(0L);
+      this.startCount = new AtomicLong(0L);
+      this.startTotalTime = new AtomicLong(0L);
+      this.startMaxTime = new AtomicLong(0L);
+   }
+
+   private void writeObject(ObjectOutputStream out) throws IOException
+   {
+      out.defaultWriteObject();
+      out.writeInt(maxPoolSize);
+   }
+
+   private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
+   {
+      in.defaultReadObject();
+      init(in.readInt());
+   }
+
+   /**
+    * toString
+    * @return The value
+    */
+   public String toString()
+   {
+      StringBuilder sb = new StringBuilder();
+
+      sb.append("PoolStatistics@").append(Integer.toHexString(System.identityHashCode(this)));
+
+      sb.append("[");
+
+      sb.append("Enabled=").append(isEnabled());
+      sb.append(",");
+      sb.append(ACTIVE_COUNT).append("=").append(getActiveCount());
+      sb.append(",");
+      sb.append(AVAILABLE_COUNT).append("=").append(getAvailableCount());
+      sb.append(",");
+      sb.append(AVERAGE_BLOCKING_TIME).append("=").append(getAverageBlockingTime());
+      sb.append(",");
+      sb.append(AVERAGE_CREATION_TIME).append("=").append(getAverageCreationTime());
+      sb.append(",");
+      sb.append(AVERAGE_GET_TIME).append("=").append(getAverageGetTime());
+      sb.append(",");
+      sb.append(AVERAGE_POOL_TIME).append("=").append(getAveragePoolTime());
+      sb.append(",");
+      sb.append(AVERAGE_USAGE_TIME).append("=").append(getAverageUsageTime());
+      sb.append(",");
+      sb.append(BLOCKING_FAILURE_COUNT).append("=").append(getBlockingFailureCount());
+      sb.append(",");
+      sb.append(CREATED_COUNT).append("=").append(getCreatedCount());
+      sb.append(",");
+      sb.append(DESTROYED_COUNT).append("=").append(getDestroyedCount());
+      sb.append(",");
+      sb.append(IDLE_COUNT).append("=").append(getIdleCount());
+      sb.append(",");
+      sb.append(IN_USE_COUNT).append("=").append(getInUseCount());
+      sb.append(",");
+      sb.append(MAX_CREATION_TIME).append("=").append(getMaxCreationTime());
+      sb.append(",");
+      sb.append(MAX_GET_TIME).append("=").append(getMaxGetTime());
+      sb.append(",");
+      sb.append(MAX_POOL_TIME).append("=").append(getMaxPoolTime());
+      sb.append(",");
+      sb.append(MAX_USAGE_TIME).append("=").append(getMaxUsageTime());
+      sb.append(",");
+      sb.append(MAX_USED_COUNT).append("=").append(getMaxUsedCount());
+      sb.append(",");
+      sb.append(MAX_WAIT_COUNT).append("=").append(getMaxWaitCount());
+      sb.append(",");
+      sb.append(MAX_WAIT_TIME).append("=").append(getMaxWaitTime());
+      sb.append(",");
+      sb.append(TIMED_OUT).append("=").append(getTimedOut());
+      sb.append(",");
+      sb.append(TOTAL_BLOCKING_TIME).append("=").append(getTotalBlockingTime());
+      sb.append(",");
+      sb.append(TOTAL_CREATION_TIME).append("=").append(getTotalCreationTime());
+      sb.append(",");
+      sb.append(TOTAL_GET_TIME).append("=").append(getTotalGetTime());
+      sb.append(",");
+      sb.append(TOTAL_POOL_TIME).append("=").append(getTotalPoolTime());
+      sb.append(",");
+      sb.append(TOTAL_USAGE_TIME).append("=").append(getTotalUsageTime());
+      sb.append(",");
+      sb.append(WAIT_COUNT).append("=").append(getWaitCount());
+
+      sb.append(",");
+      sb.append(XA_COMMIT_COUNT).append("=").append(getCommitCount());
+      sb.append(",");
+      sb.append(XA_COMMIT_AVERAGE_TIME).append("=").append(getCommitAverageTime());
+      sb.append(",");
+      sb.append(XA_COMMIT_TOTAL_TIME).append("=").append(getCommitTotalTime());
+      sb.append(",");
+      sb.append(XA_COMMIT_MAX_TIME).append("=").append(getCommitMaxTime());
+      sb.append(",");
+      sb.append(XA_END_COUNT).append("=").append(getEndCount());
+      sb.append(",");
+      sb.append(XA_END_AVERAGE_TIME).append("=").append(getEndAverageTime());
+      sb.append(",");
+      sb.append(XA_END_TOTAL_TIME).append("=").append(getEndTotalTime());
+      sb.append(",");
+      sb.append(XA_END_MAX_TIME).append("=").append(getEndMaxTime());
+      sb.append(",");
+      sb.append(XA_FORGET_COUNT).append("=").append(getForgetCount());
+      sb.append(",");
+      sb.append(XA_FORGET_AVERAGE_TIME).append("=").append(getForgetAverageTime());
+      sb.append(",");
+      sb.append(XA_FORGET_TOTAL_TIME).append("=").append(getForgetTotalTime());
+      sb.append(",");
+      sb.append(XA_FORGET_MAX_TIME).append("=").append(getForgetMaxTime());
+      sb.append(",");
+      sb.append(XA_PREPARE_COUNT).append("=").append(getPrepareCount());
+      sb.append(",");
+      sb.append(XA_PREPARE_AVERAGE_TIME).append("=").append(getPrepareAverageTime());
+      sb.append(",");
+      sb.append(XA_PREPARE_TOTAL_TIME).append("=").append(getPrepareTotalTime());
+      sb.append(",");
+      sb.append(XA_PREPARE_MAX_TIME).append("=").append(getPrepareMaxTime());
+      sb.append(",");
+      sb.append(XA_RECOVER_COUNT).append("=").append(getRecoverCount());
+      sb.append(",");
+      sb.append(XA_RECOVER_AVERAGE_TIME).append("=").append(getRecoverAverageTime());
+      sb.append(",");
+      sb.append(XA_RECOVER_TOTAL_TIME).append("=").append(getRecoverTotalTime());
+      sb.append(",");
+      sb.append(XA_RECOVER_MAX_TIME).append("=").append(getRecoverMaxTime());
+      sb.append(",");
+      sb.append(XA_ROLLBACK_COUNT).append("=").append(getRollbackCount());
+      sb.append(",");
+      sb.append(XA_ROLLBACK_AVERAGE_TIME).append("=").append(getRollbackAverageTime());
+      sb.append(",");
+      sb.append(XA_ROLLBACK_TOTAL_TIME).append("=").append(getRollbackTotalTime());
+      sb.append(",");
+      sb.append(XA_ROLLBACK_MAX_TIME).append("=").append(getRollbackMaxTime());
+      sb.append(",");
+      sb.append(XA_START_COUNT).append("=").append(getStartCount());
+      sb.append(",");
+      sb.append(XA_START_AVERAGE_TIME).append("=").append(getStartAverageTime());
+      sb.append(",");
+      sb.append(XA_START_TOTAL_TIME).append("=").append(getStartTotalTime());
+      sb.append(",");
+      sb.append(XA_START_MAX_TIME).append("=").append(getStartMaxTime());
+
+      sb.append("]");
+      
+      return sb.toString();
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/SecurityActions.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/SecurityActions.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/SecurityActions.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,88 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2013, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager.pool;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Privileged Blocks
+ * 
+ * @author Jesper Pedersen 
+ */
+class SecurityActions
+{
+   /**
+    * Get a system property
+    * @param name The property name
+    * @return The property value
+    */
+   static String getSystemProperty(final String name)
+   {
+      return AccessController.doPrivileged(new PrivilegedAction() 
+      {
+         public String run()
+         {
+            return System.getProperty(name);
+         }
+      });
+   }
+
+   /**
+    * Get the classloader.
+    * @param c The class
+    * @return The classloader
+    */
+   static ClassLoader getClassLoader(final Class> c)
+   {
+      if (System.getSecurityManager() == null)
+         return c.getClassLoader();
+
+      return AccessController.doPrivileged(new PrivilegedAction()
+      {
+         public ClassLoader run()
+         {
+            return c.getClassLoader();
+         }
+      });
+   }
+
+   /**
+    * Get stack trace
+    * @param t The thread
+    * @return The trace
+    */
+   static StackTraceElement[] getStackTrace(final Thread t)
+   {
+      if (System.getSecurityManager() == null)
+         return t.getStackTrace();
+
+      return AccessController.doPrivileged(new PrivilegedAction() 
+      {
+         public StackTraceElement[] run()
+         {
+            return t.getStackTrace();
+         }
+      });
+   }
+
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/Capacity.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/Capacity.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/Capacity.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,42 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2013, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager.pool.api;
+
+/**
+ * The capacity policy
+ *
+ * @author Jesper Pedersen 
+ */
+public interface Capacity
+{
+   /**
+    * Get the incrementer policy
+    * @return The policy; can be null for container default policy
+    */
+   public CapacityIncrementer getIncrementer();
+
+   /**
+    * Get the decrementer policy
+    * @return The policy; can be null for container default policy
+    */
+   public CapacityDecrementer getDecrementer();
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/CapacityDecrementer.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/CapacityDecrementer.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/CapacityDecrementer.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,43 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2013, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager.pool.api;
+
+import org.jboss.jca.core.connectionmanager.listener.ConnectionListener;
+
+/**
+ * The capacity decrementer policy
+ *
+ * @author Jesper Pedersen 
+ */
+public interface CapacityDecrementer
+{
+   /**
+    * Should the connection listener be destroyed
+    * @param cl The connection listener
+    * @param timeout The timeout watermark
+    * @param currentSize The current pool size
+    * @param minPoolSize The minimum pool size
+    * @param destroyed The number of connection listeners destroyed during this call cycle
+    * @return True if the connection listener should be destroyed; otherwise false
+    */
+   public boolean shouldDestroy(ConnectionListener cl, long timeout, int currentSize, int minPoolSize, int destroyed);
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/CapacityIncrementer.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/CapacityIncrementer.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/CapacityIncrementer.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,39 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2013, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager.pool.api;
+
+/**
+ * The capacity incrementer policy
+ *
+ * @author Jesper Pedersen 
+ */
+public interface CapacityIncrementer
+{
+   /**
+    * Should the connection listener be created
+    * @param currentSize The current pool size
+    * @param maxSize The maximum pool size
+    * @param created The number of connection listeners created during this call cycle
+    * @return True if a connection listener should be created; otherwise false
+    */
+   public boolean shouldCreate(int currentSize, int maxSize, int created);
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/Pool.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/Pool.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/Pool.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,205 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2006, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager.pool.api;
+
+import org.jboss.jca.core.CoreLogger;
+import org.jboss.jca.core.connectionmanager.ConnectionManager;
+import org.jboss.jca.core.connectionmanager.listener.ConnectionListener;
+import org.jboss.jca.core.connectionmanager.pool.PoolStatisticsImpl;
+import org.jboss.jca.core.connectionmanager.pool.mcp.ManagedConnectionPool;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.ConnectionRequestInfo;
+import javax.resource.spi.ManagedConnection;
+import javax.resource.spi.ManagedConnectionFactory;
+import javax.security.auth.Subject;
+import javax.transaction.Transaction;
+
+/**
+ * A pool.
+ *
+ * @author Gurkan Erdogdu 
+ * @author David Jencks 
+ * @author Jesper Pedersen 
+ */
+public interface Pool extends org.jboss.jca.core.api.connectionmanager.pool.Pool
+{
+   /**
+    * Sets pool name.
+    * @param poolName pool name
+    */
+   public void setName(String poolName);
+   
+   /**
+    * Is sharable
+    * @return The value
+    */
+   public boolean isSharable();
+
+   /**
+    * Retrieve the managed connection factory for this pool.
+    * 
+    * @return the managed connection factory
+    */ 
+   public ManagedConnectionFactory getManagedConnectionFactory();
+
+   /**
+    * Set the connection manager
+    * 
+    * @param cm the connection manager
+    */
+   public void setConnectionManager(ConnectionManager cm);
+
+   /**
+    * Get the lock
+    * @return The value
+    */
+   public Semaphore getLock();
+
+   /**
+    * Get the capacity policy
+    * @return The value
+    */
+   public Capacity getCapacity();
+
+   /**
+    * Is the pool a FIFO or FILO pool
+    * @return True if FIFO
+    */
+   public boolean isFIFO();
+
+   /**
+    * Set the capacity policy
+    * @param c The value
+    */
+   public void setCapacity(Capacity c);
+
+   /**
+    * Get the interleaving flag
+    * @return The value
+    */
+   public boolean isInterleaving();
+
+   /**
+    * Set the interleaving flag
+    * @param v The value
+    */
+   public void setInterleaving(boolean v);
+
+   /**
+    * Is the pool idle
+    * @return True if idle, otherwise false
+    */
+   public boolean isIdle();
+
+   /**
+    * Is the pool full
+    * @return True if full, otherwise false
+    */
+   public boolean isFull();
+
+   /**
+    * Get internal statistics
+    * @return The value
+    */
+   public PoolStatisticsImpl getInternalStatistics();
+
+   /**
+    * Get a connection
+    * 
+    * @param trackByTransaction for transaction stickiness
+    * @param subject the subject for connection
+    * @param cri the connection request information
+    * @return a connection event listener wrapping the connection
+    * @throws ResourceException for any error
+    */
+   public ConnectionListener getConnection(Transaction trackByTransaction, Subject subject, ConnectionRequestInfo cri)
+      throws ResourceException;
+
+   /**
+    * Find a connection listener
+    * @param mc The managed connection
+    * @return The connection listener
+    */
+   public ConnectionListener findConnectionListener(ManagedConnection mc);
+
+   /**
+    * Find a connection listener
+    * @param mc The managed connection
+    * @param connection The connection
+    * @return The connection listener
+    */
+   public ConnectionListener findConnectionListener(ManagedConnection mc, Object connection);
+
+   /**
+    * Return a connection
+    * 
+    * @param cl the connection event listener wrapping the connection
+    * @param kill whether to destroy the managed connection
+    * @throws ResourceException for any error
+    */
+   public void returnConnection(ConnectionListener cl, boolean kill) 
+      throws ResourceException;
+
+   /**
+    * Has an existing connection
+    * 
+    * @param subject the subject for connection
+    * @param cri the connection request information
+    * @return true if there is an existing connection enlisted, otherwise false
+    */
+   public boolean hasConnection(Subject subject, ConnectionRequestInfo cri);
+
+   /**
+    * Is shutdown
+    * @return The value
+    */
+   public boolean isShutdown();
+
+   /**
+    * Shutdown the pool
+    */
+   public void shutdown();
+
+   /**
+    * Prepare Shutdown
+    */
+   public void prepareShutdown();
+
+   /**
+    * Cancel shutdown
+    * @return True if the shutdown was canceled; false otherwise
+    */
+   public boolean cancelShutdown();
+
+   /**
+    * Remove the matching managed connection pool if the pool is empty
+    * @param pool The pool
+    */
+   public void emptyManagedConnectionPool(ManagedConnectionPool pool);
+
+   /**
+    * Get the logger
+    * @return The value
+    */
+   public CoreLogger getLogger();
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/PoolFactory.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/PoolFactory.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/PoolFactory.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,93 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2008-2009, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager.pool.api;
+
+import org.jboss.jca.core.api.connectionmanager.pool.PoolConfiguration;
+import org.jboss.jca.core.connectionmanager.pool.strategy.OnePool;
+import org.jboss.jca.core.connectionmanager.pool.strategy.PoolByCri;
+import org.jboss.jca.core.connectionmanager.pool.strategy.PoolBySubject;
+import org.jboss.jca.core.connectionmanager.pool.strategy.PoolBySubjectAndCri;
+import org.jboss.jca.core.connectionmanager.pool.strategy.ReauthPool;
+
+import javax.resource.spi.ManagedConnectionFactory;
+
+/**
+ * The pool factory. 
+ * @author Jesper Pedersen 
+ */
+public class PoolFactory
+{
+   /**
+    * Constructor
+    */
+   public PoolFactory()
+   {
+   }
+
+   /**
+    * Create a pool
+    * @param strategy The pool strategy
+    * @param mcf The managed connection factory
+    * @param pc The pool configuration
+    * @param noTxSeparatePools no-tx separate pool
+    * @param sharable Are the connections sharable
+    * @param mcp ManagedConnectionPool
+    * @return The pool instance
+    */
+   public Pool create(final PoolStrategy strategy,
+                      final ManagedConnectionFactory mcf,
+                      final PoolConfiguration pc,
+                      final boolean noTxSeparatePools,
+                      final boolean sharable,
+                      final String mcp)
+   {
+      if (strategy == null)
+         throw new IllegalArgumentException("Strategy is null");
+
+      if (mcf == null)
+         throw new IllegalArgumentException("MCF is null");
+
+      if (pc == null)
+         throw new IllegalArgumentException("PoolConfiguration is null");
+
+      switch (strategy)
+      {
+         case POOL_BY_CRI:
+            return new PoolByCri(mcf, pc, noTxSeparatePools, sharable, mcp);
+
+         case POOL_BY_SUBJECT:
+            return new PoolBySubject(mcf, pc, noTxSeparatePools, sharable, mcp);
+
+         case POOL_BY_SUBJECT_AND_CRI:
+            return new PoolBySubjectAndCri(mcf, pc, noTxSeparatePools, sharable, mcp);
+
+         case ONE_POOL:
+            return new OnePool(mcf, pc, noTxSeparatePools, sharable, mcp);
+
+         case REAUTH:
+            return new ReauthPool(mcf, pc, noTxSeparatePools, sharable, mcp);
+      }
+
+      throw new IllegalArgumentException("Unknown strategy " + strategy);
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/PoolStrategy.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/PoolStrategy.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/PoolStrategy.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,45 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2011, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager.pool.api;
+
+/**
+ * Defines a pool strategy. 
+ * @author Jesper Pedersen 
+ */
+public enum PoolStrategy
+{
+   /** POOL_BY_CRI */
+   POOL_BY_CRI,
+
+   /** POOL_BY_SUBJECT */
+   POOL_BY_SUBJECT,
+
+   /** POOL_BY_SUBJECT_AND_CRI */
+   POOL_BY_SUBJECT_AND_CRI,
+
+   /** ONE_POOL */
+   ONE_POOL,
+
+   /** REAUTH */
+   REAUTH
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/PrefillPool.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/PrefillPool.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/PrefillPool.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,44 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2006, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager.pool.api;
+
+import javax.resource.spi.ConnectionRequestInfo;
+import javax.security.auth.Subject;
+
+/**
+ * Prefill pool allows for prefilling connection pools.
+ * 
+ * @author Weston Price 
+ * @author Jesper Pedersen 
+ */
+public interface PrefillPool extends Pool
+{
+   /**
+    * Prefill the connection pool
+    * 
+    * @param subject the subject the subject 
+    * @param cri the connection request info
+    * @param noTxnSeperatePool whether or not we are seperating non transaction and transaction pools
+    *   
+    */
+   public void prefill(Subject subject, ConnectionRequestInfo cri, boolean noTxnSeperatePool);
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/Semaphore.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/Semaphore.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/Semaphore.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,100 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2010, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager.pool.api;
+
+import org.jboss.jca.core.connectionmanager.pool.PoolStatisticsImpl;
+
+import java.util.Collection;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A semaphore implementation that supports statistics
+ *
+ * @author Jesper Pedersen 
+ */
+public class Semaphore extends java.util.concurrent.Semaphore
+{
+   /** Serial version uid */
+   private static final long serialVersionUID = 4L;
+
+   /** Max size */
+   private int maxSize;
+
+   /** Statistics */
+   private PoolStatisticsImpl statistics;
+
+   /**
+    * Constructor
+    * @param maxSize The maxumum size
+    * @param fairness The fairness
+    * @param statistics The statistics module
+    */
+   public Semaphore(int maxSize, boolean fairness, PoolStatisticsImpl statistics)
+   {
+      super(maxSize, fairness);
+      this.maxSize = maxSize;
+      this.statistics = statistics;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public boolean tryAcquire(long timeout, TimeUnit unit) throws InterruptedException
+   {
+      if (statistics.isEnabled())
+         statistics.setMaxWaitCount(getQueueLength());
+
+      boolean result = super.tryAcquire(timeout, unit);
+
+      if (result && statistics.isEnabled())
+      {
+         statistics.setInUsedCount(maxSize - availablePermits());
+      }
+
+      return result;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public void release()
+   {
+      super.release();
+
+      if (statistics.isEnabled())
+      {
+         statistics.setInUsedCount(maxSize - availablePermits());
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public Collection getQueuedThreads()
+   {
+      return super.getQueuedThreads();
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/package.html
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/package.html	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/api/package.html	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,3 @@
+
+This package contains the connection pool api.
+
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/CapacityFactory.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/CapacityFactory.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/CapacityFactory.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,243 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2013, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager.pool.capacity;
+
+import org.jboss.jca.core.CoreLogger;
+import org.jboss.jca.core.connectionmanager.pool.api.CapacityDecrementer;
+import org.jboss.jca.core.connectionmanager.pool.api.CapacityIncrementer;
+import org.jboss.jca.core.util.Injection;
+
+import java.util.Map;
+
+import org.jboss.logging.Logger;
+
+/**
+ * The capacity factory
+ *
+ * @author Jesper Pedersen 
+ */
+public class CapacityFactory
+{
+   /** The logger */
+   private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, CapacityFactory.class.getName());
+
+   /**
+    * Constructor
+    */
+   private CapacityFactory()
+   {
+   }
+
+   /**
+    * Create a capacity instance based on the metadata
+    * @param metadata The metadata
+    * @param isCRI Is the pool CRI based
+    * @return The instance
+    */
+   public static org.jboss.jca.core.connectionmanager.pool.api.Capacity
+   create(org.jboss.jca.common.api.metadata.common.Capacity metadata,
+          boolean isCRI)
+   {
+      if (metadata == null)
+         return DefaultCapacity.INSTANCE;
+
+      CapacityIncrementer incrementer = null;
+      CapacityDecrementer decrementer = null;
+
+      // Incrementer
+      if (metadata.getIncrementer() != null && metadata.getIncrementer().getClassName() != null)
+      {
+         incrementer = loadIncrementer(metadata.getIncrementer().getClassName());
+
+         if (incrementer != null)
+         {
+            if (metadata.getIncrementer().getConfigPropertiesMap().size() > 0)
+            {
+               Injection injector = new Injection();
+
+               Map properties = metadata.getIncrementer().getConfigPropertiesMap();
+               for (Map.Entry property : properties.entrySet())
+               {
+                  try
+                  {
+                     injector.inject(incrementer, property.getKey(), property.getValue());
+                  }
+                  catch (Throwable t)
+                  {
+                     log.invalidCapacityOption(property.getKey(),
+                                               property.getValue(), incrementer.getClass().getName());
+                  }
+               }
+            }
+         }
+         else
+         {
+            log.invalidCapacityIncrementer(metadata.getIncrementer().getClassName());
+         }
+      }
+
+      if (incrementer == null)
+         incrementer = DefaultCapacity.DEFAULT_INCREMENTER;
+
+      // Decrementer
+      if (metadata.getDecrementer() != null && metadata.getDecrementer().getClassName() != null)
+      {
+         if (!isCRI)
+         {
+            decrementer = loadDecrementer(metadata.getDecrementer().getClassName());
+
+            if (decrementer != null)
+            {
+               if (metadata.getDecrementer().getConfigPropertiesMap().size() > 0)
+               {
+                  Injection injector = new Injection();
+
+                  Map properties = metadata.getDecrementer().getConfigPropertiesMap();
+                  for (Map.Entry property : properties.entrySet())
+                  {
+                     try
+                     {
+                        injector.inject(decrementer, property.getKey(), property.getValue());
+                     }
+                     catch (Throwable t)
+                     {
+                        log.invalidCapacityOption(property.getKey(),
+                                                  property.getValue(), decrementer.getClass().getName());
+                     }
+                  }
+               }
+            }
+            else
+            {
+               log.invalidCapacityDecrementer(metadata.getDecrementer().getClassName());
+            }
+         }
+         else
+         {
+            // Explicit allow TimedOutDecrementer, MinPoolSizeDecrementer and SizeDecrementer for CRI based pools
+            if (TimedOutDecrementer.class.getName().equals(metadata.getDecrementer().getClassName()) ||
+                TimedOutFIFODecrementer.class.getName().equals(metadata.getDecrementer().getClassName()) ||
+                MinPoolSizeDecrementer.class.getName().equals(metadata.getDecrementer().getClassName()) ||
+                SizeDecrementer.class.getName().equals(metadata.getDecrementer().getClassName()))
+            {
+               decrementer = loadDecrementer(metadata.getDecrementer().getClassName());
+
+               if (metadata.getDecrementer().getConfigPropertiesMap().size() > 0)
+               {
+                  Injection injector = new Injection();
+
+                  Map properties = metadata.getDecrementer().getConfigPropertiesMap();
+                  for (Map.Entry property : properties.entrySet())
+                  {
+                     try
+                     {
+                        injector.inject(decrementer, property.getKey(), property.getValue());
+                     }
+                     catch (Throwable t)
+                     {
+                        log.invalidCapacityOption(property.getKey(),
+                                                  property.getValue(), decrementer.getClass().getName());
+                     }
+                  }
+               }
+            }
+            else
+            {
+               log.invalidCapacityDecrementer(metadata.getDecrementer().getClassName());
+            }
+         }
+      }
+
+      if (decrementer == null)
+         decrementer = DefaultCapacity.DEFAULT_DECREMENTER;
+
+      return new ExplicitCapacity(incrementer, decrementer);
+   }
+
+   /**
+    * Load the incrementer
+    * @param clz The incrementer class name
+    * @return The incrementer
+    */
+   private static CapacityIncrementer loadIncrementer(String clz)
+   {
+      Object result = loadClass(clz);
+
+      if (result != null && result instanceof CapacityIncrementer)
+      {
+         return (CapacityIncrementer)result;
+      }
+
+      log.debugf("%s wasn't a CapacityIncrementer", clz);
+
+      return null;
+   }
+
+   /**
+    * Load the decrementer
+    * @param clz The decrementer class name
+    * @return The decrementer
+    */
+   private static CapacityDecrementer loadDecrementer(String clz)
+   {
+      Object result = loadClass(clz);
+
+      if (result != null && result instanceof CapacityDecrementer)
+      {
+         return (CapacityDecrementer)result;
+      }
+
+      log.debugf("%s wasn't a CapacityDecrementer", clz);
+
+      return null;
+   }
+
+   /**
+    * Load the class
+    * @param clz The class name
+    * @return The object
+    */
+   private static Object loadClass(String clz)
+   {
+      try
+      {
+         Class> c = Class.forName(clz, true, SecurityActions.getClassLoader(CapacityFactory.class));
+         return c.newInstance();
+      }
+      catch (Throwable t)
+      {
+         log.tracef("Throwable while loading %s using own classloader: %s", clz, t.getMessage());
+      }
+
+      try
+      {
+         Class> c = Class.forName(clz, true, SecurityActions.getThreadContextClassLoader());
+         return c.newInstance();
+      }
+      catch (Throwable t)
+      {
+         log.tracef("Throwable while loading %s using TCCL: %s", clz, t.getMessage());
+      }
+
+      return null;
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/DefaultCapacity.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/DefaultCapacity.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/DefaultCapacity.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,66 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2013, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager.pool.capacity;
+
+import org.jboss.jca.core.connectionmanager.pool.api.Capacity;
+import org.jboss.jca.core.connectionmanager.pool.api.CapacityDecrementer;
+import org.jboss.jca.core.connectionmanager.pool.api.CapacityIncrementer;
+
+/**
+ * The default capacity policy
+ *
+ * @author Jesper Pedersen 
+ */
+public class DefaultCapacity implements Capacity
+{
+   /** The instance */
+   public static final Capacity INSTANCE = new DefaultCapacity();
+
+   /** The default incrementer */
+   public static final CapacityIncrementer DEFAULT_INCREMENTER = null;
+
+   /** The default decrementer */
+   public static final CapacityDecrementer DEFAULT_DECREMENTER = new TimedOutDecrementer();
+
+   /**
+    * Constructor
+    */
+   private DefaultCapacity()
+   {
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public CapacityIncrementer getIncrementer()
+   {
+      return DEFAULT_INCREMENTER;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public CapacityDecrementer getDecrementer()
+   {
+      return DEFAULT_DECREMENTER;
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/ExplicitCapacity.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/ExplicitCapacity.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/ExplicitCapacity.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,67 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2013, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager.pool.capacity;
+
+import org.jboss.jca.core.connectionmanager.pool.api.Capacity;
+import org.jboss.jca.core.connectionmanager.pool.api.CapacityDecrementer;
+import org.jboss.jca.core.connectionmanager.pool.api.CapacityIncrementer;
+
+/**
+ * Explicit capacity policy
+ *
+ * @author Jesper Pedersen 
+ */
+public class ExplicitCapacity implements Capacity
+{
+   /** The incrementer */
+   private CapacityIncrementer incrementer;
+
+   /** The decrementer */
+   private CapacityDecrementer decrementer;
+
+   /**
+    * Constructor
+    * @param incrementer The incrementer
+    * @param decrementer The decrementer
+    */
+   public ExplicitCapacity(CapacityIncrementer incrementer, CapacityDecrementer decrementer)
+   {
+      this.incrementer = incrementer;
+      this.decrementer = decrementer;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public CapacityIncrementer getIncrementer()
+   {
+      return incrementer;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public CapacityDecrementer getDecrementer()
+   {
+      return decrementer;
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/MaxPoolSizeIncrementer.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/MaxPoolSizeIncrementer.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/MaxPoolSizeIncrementer.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,55 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2013, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager.pool.capacity;
+
+import org.jboss.jca.core.connectionmanager.pool.api.CapacityIncrementer;
+
+/**
+ * Keep incrementing until max-pool-size is reached
+ *
+ * @author Jesper Pedersen 
+ */
+public class MaxPoolSizeIncrementer implements CapacityIncrementer
+{
+   /**
+    * Constructor
+    */
+   public MaxPoolSizeIncrementer()
+   {
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean shouldCreate(int currentSize, int maxSize, int created)
+   {
+      return currentSize < maxSize;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public String toString()
+   {
+      return getClass().getName();
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/MinPoolSizeDecrementer.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/MinPoolSizeDecrementer.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/MinPoolSizeDecrementer.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,56 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2013, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager.pool.capacity;
+
+import org.jboss.jca.core.connectionmanager.listener.ConnectionListener;
+import org.jboss.jca.core.connectionmanager.pool.api.CapacityDecrementer;
+
+/**
+ * Keep destroying connection listeners until min-pool-size is reached
+ *
+ * @author Jesper Pedersen 
+ */
+public class MinPoolSizeDecrementer implements CapacityDecrementer
+{
+   /**
+    * Constructor
+    */
+   public MinPoolSizeDecrementer()
+   {
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean shouldDestroy(ConnectionListener cl, long timeout, int currentSize, int minPoolSize, int destroyed)
+   {
+      return currentSize > minPoolSize;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public String toString()
+   {
+      return getClass().getName();
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/SecurityActions.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/SecurityActions.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/SecurityActions.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,74 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2013, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager.pool.capacity;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Privileged Blocks
+ * 
+ * @author Jesper Pedersen 
+ */
+class SecurityActions
+{
+   /**
+    * Get the classloader.
+    * @param c The class
+    * @return The classloader
+    */
+   static ClassLoader getClassLoader(final Class> c)
+   {
+      if (System.getSecurityManager() == null)
+         return c.getClassLoader();
+
+      return AccessController.doPrivileged(new PrivilegedAction()
+      {
+         public ClassLoader run()
+         {
+            return c.getClassLoader();
+         }
+      });
+   }
+
+   /**
+    * Get the context classloader.
+    * @return The classloader
+    */
+   public static ClassLoader getThreadContextClassLoader()
+   {
+      if (System.getSecurityManager() == null)
+      {
+         return Thread.currentThread().getContextClassLoader();
+      }
+      else
+      {
+         return AccessController.doPrivileged(new PrivilegedAction()
+         {
+            public ClassLoader run()
+            {
+               return Thread.currentThread().getContextClassLoader();
+            }
+         });
+      }
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/SizeDecrementer.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/SizeDecrementer.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/SizeDecrementer.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,71 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2013, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager.pool.capacity;
+
+import org.jboss.jca.core.connectionmanager.listener.ConnectionListener;
+import org.jboss.jca.core.connectionmanager.pool.api.CapacityDecrementer;
+
+/**
+ * Decrement until the defined number of connection has been destroyed.
+ *
+ * Default value is 1
+ * @author Jesper Pedersen 
+ */
+public class SizeDecrementer implements CapacityDecrementer
+{
+   /** Size */
+   private int size;
+
+   /**
+    * Constructor
+    */
+   public SizeDecrementer()
+   {
+      this.size = 1;
+   }
+
+   /**
+    * Set the size
+    * @param v The value
+    */
+   public void setSize(int v)
+   {
+      if (v > 0)
+         size = v;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean shouldDestroy(ConnectionListener cl, long timeout, int currentSize, int minPoolSize, int destroyed)
+   {
+      return size > destroyed;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public String toString()
+   {
+      return getClass().getName() + "(" + size + ")";
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/SizeIncrementer.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/SizeIncrementer.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/SizeIncrementer.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,70 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2013, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager.pool.capacity;
+
+import org.jboss.jca.core.connectionmanager.pool.api.CapacityIncrementer;
+
+/**
+ * Increment until the defined number of connection has been created.
+ *
+ * Default value is 1
+ * @author Jesper Pedersen 
+ */
+public class SizeIncrementer implements CapacityIncrementer
+{
+   /** Size */
+   private int size;
+
+   /**
+    * Constructor
+    */
+   public SizeIncrementer()
+   {
+      this.size = 1;
+   }
+
+   /**
+    * Set the size
+    * @param v The value
+    */
+   public void setSize(int v)
+   {
+      if (v > 0)
+         size = v;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean shouldCreate(int currentSize, int maxSize, int created)
+   {
+      return size > created;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public String toString()
+   {
+      return getClass().getName() + "(" + size + ")";
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/TimedOutDecrementer.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/TimedOutDecrementer.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/TimedOutDecrementer.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,56 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2013, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager.pool.capacity;
+
+import org.jboss.jca.core.connectionmanager.listener.ConnectionListener;
+import org.jboss.jca.core.connectionmanager.pool.api.CapacityDecrementer;
+
+/**
+ * Decrement all timed out connection listeners
+ *
+ * @author Jesper Pedersen 
+ */
+public class TimedOutDecrementer implements CapacityDecrementer
+{
+   /**
+    * Constructor
+    */
+   public TimedOutDecrementer()
+   {
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean shouldDestroy(ConnectionListener cl, long timeout, int currentSize, int minPoolSize, int destroyed)
+   {
+      return cl.isTimedOut(timeout);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public String toString()
+   {
+      return getClass().getName();
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/TimedOutFIFODecrementer.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/TimedOutFIFODecrementer.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/TimedOutFIFODecrementer.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,37 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2015, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager.pool.capacity;
+
+/**
+ * Decrement all timed out connection listeners (FIFO marker)
+ *
+ * @author Jesper Pedersen 
+ */
+public class TimedOutFIFODecrementer extends TimedOutDecrementer
+{
+   /**
+    * Constructor
+    */
+   public TimedOutFIFODecrementer()
+   {
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/WatermarkDecrementer.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/WatermarkDecrementer.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/WatermarkDecrementer.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,73 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2013, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager.pool.capacity;
+
+import org.jboss.jca.core.connectionmanager.listener.ConnectionListener;
+import org.jboss.jca.core.connectionmanager.pool.api.CapacityDecrementer;
+
+/**
+ * Decrement until the defined pool size is reached.
+ *
+ * Default value is min-pool-size
+ * @author Jesper Pedersen 
+ */
+public class WatermarkDecrementer implements CapacityDecrementer
+{
+   /** Watermark */
+   private int watermark;
+
+   /**
+    * Constructor
+    */
+   public WatermarkDecrementer()
+   {
+      this.watermark = -1;
+   }
+
+   /**
+    * Set the watermark
+    * @param v The value
+    */
+   public void setWatermark(int v)
+   {
+      watermark = v;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean shouldDestroy(ConnectionListener cl, long timeout, int currentSize, int minPoolSize, int destroyed)
+   {
+      if (watermark < 0)
+         return currentSize > minPoolSize;
+
+      return watermark < currentSize;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public String toString()
+   {
+      return getClass().getName() + "(" + watermark + ")";
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/WatermarkIncrementer.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/WatermarkIncrementer.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/WatermarkIncrementer.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,72 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2013, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager.pool.capacity;
+
+import org.jboss.jca.core.connectionmanager.pool.api.CapacityIncrementer;
+
+/**
+ * Increment until the defined pool size is reached.
+ *
+ * Default value is max-pool-size
+ * @author Jesper Pedersen 
+ */
+public class WatermarkIncrementer implements CapacityIncrementer
+{
+   /** Watermark */
+   private int watermark;
+
+   /**
+    * Constructor
+    */
+   public WatermarkIncrementer()
+   {
+      this.watermark = -1;
+   }
+
+   /**
+    * Set the watermark
+    * @param v The value
+    */
+   public void setWatermark(int v)
+   {
+      watermark = v;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean shouldCreate(int currentSize, int maxSize, int created)
+   {
+      if (watermark < 0)
+         return currentSize < maxSize;
+
+      return watermark > currentSize;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public String toString()
+   {
+      return getClass().getName() + "(" + watermark + ")";
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/package.html
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/package.html	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/capacity/package.html	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,3 @@
+
+This package contains the capacity policy implementations
+
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/idle/IdleConnectionRemovalSupport.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/idle/IdleConnectionRemovalSupport.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/idle/IdleConnectionRemovalSupport.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,39 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2008, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager.pool.idle;
+
+/**
+ * A IdleConnectionRemovalSupport specified contract for a pool that is able
+ * to remove an idle connection.
+ * 
+ * @author gurkanerdogdu
+ * @author Weston Price 
+ * @version $Revision$
+ */
+public interface IdleConnectionRemovalSupport
+{
+   /**
+    * Pool removes idle connections.
+    */
+   public void removeIdleConnections();
+   
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/idle/IdleRemover.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/idle/IdleRemover.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/idle/IdleRemover.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,306 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2008-2011, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager.pool.idle;
+
+import org.jboss.jca.core.CoreLogger;
+
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.jboss.logging.Logger;
+
+/**
+ * Idle remover
+ * 
+ * @author Gurkan Erdogdu 
+ * @author Jesper Pedersen 
+ */
+public class IdleRemover
+{
+   /** Logger instance */
+   private static CoreLogger logger = Logger.getMessageLogger(CoreLogger.class, IdleRemover.class.getName());
+   
+   /** Thread name */
+   private static final String THREAD_NAME = "IdleRemover";
+   
+   /** Singleton instance */
+   private static IdleRemover instance = new IdleRemover();
+   
+   /** Registered pool instances */
+   private CopyOnWriteArrayList registeredPools = 
+      new CopyOnWriteArrayList();
+   
+   /** Executor service */
+   private ExecutorService executorService;
+   
+   /** Is the executor external */
+   private boolean isExternal;
+
+   /** The interval */
+   private long interval;
+
+   /** The next scan */
+   private long next;
+   
+   /** Shutdown */
+   private AtomicBoolean shutdown;
+
+   /** Lock */
+   private Lock lock;
+   
+   /** Condition */
+   private Condition condition;
+   
+   /**
+    * Private constructor.
+    */
+   private IdleRemover()
+   {
+      this.executorService = null;
+      this.isExternal = false;
+      this.interval = Long.MAX_VALUE;
+      this.next = Long.MAX_VALUE;
+      this.shutdown = new AtomicBoolean(false);
+      this.lock = new ReentrantLock(true);
+      this.condition = lock.newCondition();
+   }
+
+   /**
+    * Get the instance
+    * @return The value
+    */
+   public static IdleRemover getInstance()
+   {
+      return instance;
+   }
+   
+   /**
+    * Set the executor service
+    * @param v The value
+    */
+   public void setExecutorService(ExecutorService v)
+   {
+      if (v != null)
+      {
+         this.executorService = v;
+         this.isExternal = true;
+      }
+      else
+      {
+         this.executorService = null;
+         this.isExternal = false;
+      }
+   }
+
+   /**
+    * Start
+    * @exception Throwable Thrown if an error occurs
+    */
+   public void start() throws Throwable
+   {
+      if (!isExternal)
+      {
+         this.executorService = Executors.newSingleThreadExecutor(new IdleRemoverThreadFactory());
+      }
+
+      this.shutdown.set(false);
+      this.interval = Long.MAX_VALUE;
+      this.next = Long.MAX_VALUE;
+
+      this.executorService.execute(new IdleRemoverRunner());
+   }
+
+   /**
+    * Stop
+    * @exception Throwable Thrown if an error occurs
+    */
+   public void stop() throws Throwable
+   {
+      instance.shutdown.set(true);
+
+      if (!isExternal)
+      {
+         instance.executorService.shutdownNow();
+         instance.executorService = null;
+      }
+
+      instance.registeredPools.clear();
+   }
+   
+   /**
+    * Register pool for connection validation.
+    * @param mcp managed connection pool
+    * @param interval validation interval
+    */
+   public void registerPool(IdleConnectionRemovalSupport mcp, long interval)
+   {
+      logger.debugf("Register pool: %s (interval=%s)", mcp, interval);
+
+      instance.internalRegisterPool(mcp, interval);
+   }
+   
+   /**
+    * Unregister pool instance for connection validation.
+    * @param mcp pool instance
+    */
+   public void unregisterPool(IdleConnectionRemovalSupport mcp)
+   {
+      logger.debugf("Unregister pool: %s", mcp);
+
+      instance.internalUnregisterPool(mcp);
+   }
+
+   private void internalRegisterPool(IdleConnectionRemovalSupport mcp, long interval)
+   {
+      try
+      {
+         this.lock.lock();
+         
+         this.registeredPools.addIfAbsent(mcp);
+         
+         if (interval > 1 && interval / 2 < this.interval) 
+         {
+            this.interval = interval / 2;
+            long maybeNext = System.currentTimeMillis() + this.interval;
+            if (next > maybeNext && maybeNext > 0) 
+            {
+               next = maybeNext;
+               if (logger.isDebugEnabled())
+               {
+                  logger.debug("About to notify thread: old next: " + next + ", new next: " + maybeNext);
+               }               
+               
+               this.condition.signal();
+            }
+         }         
+      } 
+      finally
+      {
+         this.lock.unlock();
+      }
+   }
+   
+   private void internalUnregisterPool(IdleConnectionRemovalSupport mcp)
+   {
+      this.registeredPools.remove(mcp);
+      
+      if (this.registeredPools.size() == 0) 
+      {
+         if (logger.isDebugEnabled())
+         {
+            logger.debug("Setting interval to Long.MAX_VALUE");  
+         }
+         
+         interval = Long.MAX_VALUE;
+      }
+   }
+         
+   /**
+    * Thread factory.
+    */
+   private static class IdleRemoverThreadFactory implements ThreadFactory
+   {
+      /**
+       * {@inheritDoc}
+       */
+      public Thread newThread(Runnable r)
+      {
+         Thread thread = new Thread(r, IdleRemover.THREAD_NAME);
+         thread.setDaemon(true);
+         
+         return thread;
+      }      
+   }
+   
+   /**
+    * IdleRemoverRunner
+    */
+   private class IdleRemoverRunner implements Runnable
+   {
+      /**
+       * {@inheritDoc}
+       */
+      public void run()
+      {
+         final ClassLoader oldTccl = SecurityActions.getThreadContextClassLoader();
+         SecurityActions.setThreadContextClassLoader(IdleRemover.class.getClassLoader());
+         
+         try
+         {
+            lock.lock();
+            
+            while (!shutdown.get())
+            {
+               boolean result = instance.condition.await(instance.interval, TimeUnit.MILLISECONDS);
+
+               if (logger.isTraceEnabled())
+               {
+                  logger.trace("Result of await: " + result);
+               }
+
+               if (logger.isDebugEnabled())
+               {
+                  logger.debug("Notifying pools, interval: " + interval);  
+               }
+     
+               for (IdleConnectionRemovalSupport mcp : registeredPools)
+               {
+                  mcp.removeIdleConnections();
+               }
+
+               next = System.currentTimeMillis() + interval;
+               
+               if (next < 0)
+               {
+                  next = Long.MAX_VALUE;  
+               }
+            }            
+         }
+         catch (InterruptedException e)
+         {
+            if (!shutdown.get())
+               logger.returningConnectionValidatorInterrupted();
+         }
+         catch (RuntimeException e)
+         {
+            logger.connectionValidatorIgnoredUnexpectedRuntimeException(e);
+         }
+         catch (Exception e)
+         {
+            logger.connectionValidatorIgnoredUnexpectedError(e);
+         }         
+         finally
+         {
+            lock.unlock();  
+            SecurityActions.setThreadContextClassLoader(oldTccl);
+         }
+      }
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/idle/SecurityActions.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/idle/SecurityActions.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/idle/SecurityActions.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,83 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2008, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors. 
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager.pool.idle;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Privileged Blocks
+ * 
+ * @author Jesper Pedersen 
+ */
+class SecurityActions
+{
+   /**
+    * Get the context classloader.
+    * @return The classloader
+    */
+   public static ClassLoader getThreadContextClassLoader()
+   {
+      if (System.getSecurityManager() == null)
+      {
+         return Thread.currentThread().getContextClassLoader();
+      }
+      else
+      {
+         return AccessController.doPrivileged(new PrivilegedAction()
+         {
+            public ClassLoader run()
+            {
+               return Thread.currentThread().getContextClassLoader();
+            }
+         });
+      }
+   }
+
+   /**
+    * Set the context classloader.
+    * @param cl classloader
+    */
+   public static void setThreadContextClassLoader(final ClassLoader cl)
+   {
+      if (cl == null)
+         return;
+
+      if (System.getSecurityManager() == null)
+      {
+         Thread.currentThread().setContextClassLoader(cl);
+      }
+      else
+      {
+         AccessController.doPrivileged(new PrivilegedAction()
+         {
+            public Object run()
+            {
+               Thread.currentThread().setContextClassLoader(cl);
+
+               return null;
+            }
+         });
+      }
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/idle/package.html
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/idle/package.html	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/idle/package.html	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,3 @@
+
+This package contains the infrastructure for removing idle connections.
+
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/CapacityFiller.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/CapacityFiller.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/CapacityFiller.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,132 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2013, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager.pool.mcp;
+
+import java.util.LinkedList;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Capacity filler
+ * 
+ * @author Jesper Pedersen 
+ */
+class CapacityFiller implements Runnable
+{
+   /** Singleton instance */
+   private static final CapacityFiller INSTANCE = new CapacityFiller();
+
+   /** Managed connection pool list */
+   private final LinkedList crs = new LinkedList();
+
+   /** Filler thread */
+   private final Thread fillerThread;
+
+   /** Thread name */
+   private static final String THREAD_FILLER_NAME = "JCA CapacityFiller";
+
+   /**Thread is configured or not*/
+   private AtomicBoolean threadStarted = new AtomicBoolean(false);
+
+   /**
+    * Schedule capacity request
+    * @param cr The value
+    */
+   static void schedule(CapacityRequest cr)
+   {
+      INSTANCE.internalSchedule(cr);
+   }
+
+   /**
+    * Constructor
+    */
+   CapacityFiller()
+   {
+      fillerThread = new Thread(this, THREAD_FILLER_NAME);
+      fillerThread.setDaemon(true);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void run()
+   {
+      final ClassLoader myClassLoader = SecurityActions.getClassLoader(getClass());
+      SecurityActions.setThreadContextClassLoader(myClassLoader);
+
+      while (true)
+      {
+         boolean empty = false;
+
+         while (!empty)
+         {
+            CapacityRequest cr = null;
+
+            synchronized (crs)
+            {
+               empty = crs.isEmpty();
+               if (!empty)
+                  cr = crs.removeFirst();
+            }
+
+            if (!empty)
+            {
+               cr.getManagedConnectionPool().increaseCapacity(cr.getSubject(), cr.getConnectionRequestInfo());
+            }
+         }
+
+         try 
+         {
+            synchronized (crs)
+            {
+               while (crs.isEmpty())
+               {
+                  crs.wait();                        
+               }
+            }
+         }
+         catch (InterruptedException ie)
+         {
+            Thread.currentThread().interrupt();
+            return;
+         }
+      }
+   }
+
+   /**
+    * Internal: Schedule
+    * @param cr The value
+    */
+   private void internalSchedule(CapacityRequest cr)
+   {
+      if (this.threadStarted.compareAndSet(false, true))         
+      {
+         this.fillerThread.start();
+      }
+      
+      // Multiple instances of the same ManagedConnectionPool is allowed
+      synchronized (crs)
+      {
+         crs.addLast(cr);
+         crs.notifyAll();
+      }
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/CapacityRequest.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/CapacityRequest.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/CapacityRequest.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,138 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2013, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager.pool.mcp;
+
+import javax.resource.spi.ConnectionRequestInfo;
+import javax.security.auth.Subject;
+
+/**
+ * Represents a capacity request for a managed connection pool
+ *
+ * @author Jesper Pedersen 
+ */
+class CapacityRequest
+{
+   /** Managed connection pool */
+   private ManagedConnectionPool mcp;
+
+   /** Subject */
+   private Subject subject;
+
+   /** ConnectionRequestInfo */
+   private ConnectionRequestInfo cri;
+
+   /**
+    * Constructor
+    * @param mcp The managed connection pool
+    * @param subject The subject
+    * @param cri The connection request info object
+    */
+   CapacityRequest(ManagedConnectionPool mcp, Subject subject, ConnectionRequestInfo cri)
+   {
+      this.mcp = mcp;
+      this.subject = subject;
+      this.cri = cri;
+   }
+
+   /**
+    * Get the managed connection pool
+    * @return The value
+    */
+   ManagedConnectionPool getManagedConnectionPool()
+   {
+      return mcp;
+   }
+
+   /**
+    * Get the subject
+    * @return The value
+    */
+   Subject getSubject()
+   {
+      return subject;
+   }
+
+   /**
+    * Get the connection request info object
+    * @return The value
+    */
+   ConnectionRequestInfo getConnectionRequestInfo()
+   {
+      return cri;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public int hashCode()
+   {
+      int result = 31;
+      result += 7 * mcp.hashCode();
+      result += subject != null ? 7 * SecurityActions.hashCode(subject) : 7;
+      result += cri != null ? 7 * cri.hashCode() : 7;
+      return result;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean equals(Object obj)
+   {
+      if (this == obj)
+         return true;
+
+      if (obj == null)
+         return false;
+
+      if (!(obj instanceof CapacityRequest))
+         return false;
+
+      CapacityRequest other = (CapacityRequest) obj;
+
+      if (mcp == null)
+      {
+         if (other.mcp != null)
+            return false;
+      }
+      else if (System.identityHashCode(mcp) != System.identityHashCode(other.mcp))
+         return false;
+
+      if (subject == null)
+      {
+         if (other.subject != null)
+            return false;
+      }
+      else if (!SecurityActions.equals(subject, other.subject))
+         return false;
+
+      if (cri == null)
+      {
+         if (other.cri != null)
+            return false;
+      }
+      else if (!cri.equals(other.cri))
+         return false;
+
+      return true;
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/FillRequest.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/FillRequest.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/FillRequest.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,107 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2012, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager.pool.mcp;
+
+/**
+ * Represents a fill request for a managed connection pool
+ *
+ * @author Jesper Pedersen 
+ */
+class FillRequest
+{
+   /** Managed connection pool */
+   private ManagedConnectionPool mcp;
+
+   /** Fill size */
+   private int fillSize;
+
+   /**
+    * Constructor
+    * @param mcp The managed connection pool
+    * @param fillSize The fill size
+    */
+   FillRequest(ManagedConnectionPool mcp, int fillSize)
+   {
+      this.mcp = mcp;
+      this.fillSize = fillSize;
+   }
+
+   /**
+    * Get the managed connection pool
+    * @return The value
+    */
+   ManagedConnectionPool getManagedConnectionPool()
+   {
+      return mcp;
+   }
+
+   /**
+    * Get the fill size
+    * @return The value
+    */
+   int getFillSize()
+   {
+      return fillSize;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public int hashCode()
+   {
+      int result = 31;
+      result += 7 * mcp.hashCode();
+      result += 7 * fillSize;
+      return result;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean equals(Object obj)
+   {
+      if (this == obj)
+         return true;
+
+      if (obj == null)
+         return false;
+
+      if (!(obj instanceof FillRequest))
+         return false;
+
+      FillRequest other = (FillRequest) obj;
+
+      if (mcp == null)
+      {
+         if (other.mcp != null)
+            return false;
+      }
+      else if (System.identityHashCode(mcp) != System.identityHashCode(other.mcp))
+         return false;
+
+      if (fillSize != other.fillSize)
+         return false;
+
+      return true;
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/LeakDumperManagedConnectionPool.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/LeakDumperManagedConnectionPool.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/LeakDumperManagedConnectionPool.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,225 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2013, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager.pool.mcp;
+
+import org.jboss.jca.core.CoreLogger;
+import org.jboss.jca.core.connectionmanager.listener.ConnectionListener;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.ConnectionRequestInfo;
+import javax.security.auth.Subject;
+
+import org.jboss.logging.Logger;
+
+/**
+ * A managed connection pool which dumps any leaks at shutdown
+ *
+ * @author Jesper Pedersen 
+ */
+public class LeakDumperManagedConnectionPool extends SemaphoreArrayListManagedConnectionPool
+{
+   /** The logger */
+   private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class,
+                                                           LeakDumperManagedConnectionPool.class.getName());
+
+   /** Dump to special file too */
+   private static boolean useFile = false;
+
+   /** Special file name */
+   private static String leakFileName = null;
+
+   /** Leak lock */
+   private static Object leakLock = new Object();
+
+   /** The tracker map of connection listeners */
+   private final ConcurrentMap tracker =
+      new ConcurrentHashMap();
+
+   /** The time map of connection listeners */
+   private final ConcurrentMap times =
+      new ConcurrentHashMap();
+
+   static
+   {
+      String f = SecurityActions.getSystemProperty("ironjacamar.leaklog");
+      if (f != null && !f.trim().equals(""))
+      {
+         useFile = true;
+         leakFileName = f;
+      }
+   }
+
+   /**
+    * Constructor
+    */
+   public LeakDumperManagedConnectionPool()
+   {
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public ConnectionListener getConnection(Subject subject, ConnectionRequestInfo cri) throws ResourceException
+   {
+      ConnectionListener cl = super.getConnection(subject, cri);
+
+      tracker.put(cl, new Throwable("ALLOCATION LEAK"));
+      times.put(cl, Long.valueOf(System.currentTimeMillis()));
+
+      return cl;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public void returnConnection(ConnectionListener cl, boolean kill, boolean cleanup)
+   {
+      tracker.remove(cl);
+      times.remove(cl);
+      super.returnConnection(cl, kill, cleanup);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void connectionListenerDestroyed(ConnectionListener cl)
+   {
+      if (tracker.containsKey(cl))
+      {
+         Throwable t = tracker.get(cl);
+         Long l = times.get(cl);
+         log.connectionLeak(getPoolName(), Integer.toHexString(System.identityHashCode(cl)), l.longValue(), t);
+
+         if (useFile)
+            dump(cl, t, l.longValue());
+
+         tracker.remove(cl);
+         times.remove(cl);
+      }
+      super.connectionListenerDestroyed(cl);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public void shutdown()
+   {
+      if (tracker.size() > 0)
+      {
+         Iterator> it = tracker.entrySet().iterator();
+         while (it.hasNext())
+         {
+            Map.Entry entry = it.next();
+            Long l = times.get(entry.getKey());
+
+            log.connectionLeak(getPoolName(), Integer.toHexString(System.identityHashCode(entry.getKey())),
+                               l.longValue(), entry.getValue());
+
+            if (useFile)
+               dump(entry.getKey(), entry.getValue(), l.longValue());
+         }
+
+         tracker.clear();
+         times.clear();
+      }
+
+      super.shutdown();
+   }
+
+   private void dump(ConnectionListener cl, Throwable t, long time)
+   {
+      synchronized (leakLock)
+      {
+         OutputStream os = null;
+         try
+         {
+            os = new FileOutputStream(leakFileName, true);
+
+            PrintStream ps = new PrintStream(os, true);
+
+            ps.print("Leak detected in pool: ");
+            ps.println(getPoolName());
+
+            ps.print("  ConnectionListener: ");
+            ps.println(Integer.toHexString(System.identityHashCode(cl)));
+
+            ps.print("  Allocation timestamp: ");
+            ps.println(time);
+
+            ps.println("  Allocation stacktrack:");
+
+            t.printStackTrace(ps);
+
+            ps.println();
+
+            ps.flush();
+         }
+         catch (Exception e)
+         {
+            log.debug(e.getMessage(), e);
+         }
+         finally
+         {
+            if (os != null)
+            {
+               try
+               {
+                  os.close();
+               }
+               catch (IOException ioe)
+               {
+                  // Ignore
+               }
+            }
+         }
+      }
+   }
+
+   /**
+    * String representation
+    * @return The string
+    */
+   @Override
+   public String toString()
+   {
+      StringBuilder sb = new StringBuilder();
+
+      sb.append("LeakDumperManagedConnectionPool@").append(Integer.toHexString(System.identityHashCode(this)));
+      sb.append("[super=").append(super.toString());
+      sb.append("]");
+
+      return sb.toString();
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/ManagedConnectionPool.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/ManagedConnectionPool.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/ManagedConnectionPool.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,173 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2010, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager.pool.mcp;
+
+import org.jboss.jca.core.api.connectionmanager.pool.FlushMode;
+import org.jboss.jca.core.api.connectionmanager.pool.PoolConfiguration;
+import org.jboss.jca.core.connectionmanager.ConnectionManager;
+import org.jboss.jca.core.connectionmanager.listener.ConnectionListener;
+import org.jboss.jca.core.connectionmanager.pool.api.Pool;
+import org.jboss.jca.core.connectionmanager.pool.idle.IdleConnectionRemovalSupport;
+
+import java.util.Collection;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.ConnectionRequestInfo;
+import javax.resource.spi.ManagedConnection;
+import javax.resource.spi.ManagedConnectionFactory;
+import javax.security.auth.Subject;
+
+/**
+ * Represents a managed connection pool, which manages all connection listeners
+ *
+ * @author Jesper Pedersen 
+ */
+public interface ManagedConnectionPool extends IdleConnectionRemovalSupport
+{   
+   /**
+    * Get the last used timestamp
+    * @return The value
+    */
+   public long getLastUsed();
+
+   /**
+    * Initialize the managed connection pool
+    * 
+    * @param mcf The managed connection factory
+    * @param cm The connection manager
+    * @param subject The subject
+    * @param cri The connection request info
+    * @param pc The pool configuration
+    * @param p The pool
+    */
+   public void initialize(ManagedConnectionFactory mcf, ConnectionManager cm, Subject subject,
+                          ConnectionRequestInfo cri, PoolConfiguration pc, Pool p);
+
+   /**
+    * Returns a connection listener that wraps managed connection.
+    * @param subject subject
+    * @param cri connection request info
+    * @return connection listener wrapped managed connection
+    * @throws ResourceException exception
+    */
+   public ConnectionListener getConnection(Subject subject, ConnectionRequestInfo cri) throws ResourceException;
+   
+   /**
+    * Find a connection listener
+    * @param mc The managed connection
+    * @return The connection listener; null if the connection listener doesn't belong
+    */
+   public ConnectionListener findConnectionListener(ManagedConnection mc);
+
+   /**
+    * Find a connection listener
+    * @param mc The managed connection
+    * @param connection The connection
+    * @return The connection listener; null if the connection listener doesn't belong
+    */
+   public ConnectionListener findConnectionListener(ManagedConnection mc, Object connection);
+
+   /**
+    * Return connection to the pool.
+    * @param cl connection listener
+    * @param kill kill connection
+    */
+   public void returnConnection(ConnectionListener cl, boolean kill);
+
+   /**
+    * Checks if the pool is empty or not
+    * @return True if is emtpy; otherwise false
+    */
+   public boolean isEmpty();
+   
+   /**
+    * Is the pool idle ?
+    * @return True if idle, otherwise false
+    */
+   public boolean isIdle();
+
+   /**
+    * Checks if the pool is running or not
+    * @return True if is running; otherwise false
+    */
+   public boolean isRunning();
+
+   /**
+    * Get number of active connections
+    * @return The value
+    */
+   public int getActive();
+   
+   /**
+    * Prefill
+    */
+   public void prefill();
+   
+   /**
+    * Flush
+    * @param mode The flush mode
+    * @param toDestroy list of connection listeners to be destroyed
+    */
+   public void flush(FlushMode mode, Collection toDestroy);
+   
+   /**
+    * Shutdown
+    */
+   public void shutdown();
+   
+   /**
+    * Fill to
+    * @param size The size
+    */
+   public void fillTo(int size);
+   
+   /**
+    * Validate connecitons.
+    * @throws Exception for exception
+    */
+   public void validateConnections() throws Exception;
+
+   /**
+    * Increase capacity
+    * @param subject The subject
+    * @param cri The connection request information object
+    */
+   public void increaseCapacity(Subject subject, ConnectionRequestInfo cri);
+
+   /**
+    * Add a connection to the pool
+    * @param cl The connection listener
+    */
+   public void addConnectionListener(ConnectionListener cl);
+
+   /**
+    * Remove an idle connection from the pool
+    * @return A connection listener; null if no connection listener was available
+    */
+   public ConnectionListener removeConnectionListener();
+
+   /**
+    * Notify that a connection listener belonging to this pool was destroyed.
+    */
+   public void connectionListenerDestroyed(ConnectionListener cl);
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/ManagedConnectionPoolFactory.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/ManagedConnectionPoolFactory.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/ManagedConnectionPoolFactory.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,195 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2010, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager.pool.mcp;
+
+import org.jboss.jca.core.CoreLogger;
+import org.jboss.jca.core.api.connectionmanager.pool.PoolConfiguration;
+import org.jboss.jca.core.connectionmanager.ConnectionManager;
+import org.jboss.jca.core.connectionmanager.pool.api.Pool;
+
+import javax.resource.spi.ConnectionRequestInfo;
+import javax.resource.spi.ManagedConnectionFactory;
+import javax.security.auth.Subject;
+
+import org.jboss.logging.Logger;
+
+/**
+ * Factory to create a managed connection pool
+ *
+ * @author Jesper Pedersen 
+ */
+public class ManagedConnectionPoolFactory
+{   
+   /** The logger */
+   private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class,
+                                                           ManagedConnectionPoolFactory.class.getName());
+
+   /** Default implementation */
+   public static final String DEFAULT_IMPLEMENTATION = 
+      "org.jboss.jca.core.connectionmanager.pool.mcp.SemaphoreArrayListManagedConnectionPool";
+
+   /** Experimental implementation */
+   public static final String EXPERIMENTAL_IMPLEMENTATION = 
+      "org.jboss.jca.core.connectionmanager.pool.mcp.SemaphoreConcurrentLinkedDequeManagedConnectionPool";
+
+   /** Deprecated implementations */
+   private static final String[] DEPRECATED_IMPLEMENTATIONS = new String[] {
+      "org.jboss.jca.core.connectionmanager.pool.mcp.ArrayBlockingQueueManagedConnectionPool",
+      "org.jboss.jca.core.connectionmanager.pool.mcp.SemaphoreConcurrentLinkedQueueManagedConnectionPool"
+   };
+   
+   /** Default class definition */
+   private static Class> defaultImplementation;
+
+   /** Override */
+   private static boolean override;
+   
+   static
+   {
+      String clz = SecurityActions.getSystemProperty("ironjacamar.mcp");
+
+      if (clz != null && !clz.trim().equals(""))
+      {
+         clz = clz.trim();
+         for (String impl : DEPRECATED_IMPLEMENTATIONS)
+         {
+            if (clz.equals(impl))
+            {
+               log.deprecatedPool(clz, EXPERIMENTAL_IMPLEMENTATION);
+               clz = EXPERIMENTAL_IMPLEMENTATION;
+            }
+         }
+
+         override = true;
+      }
+      else
+      {
+         clz = DEFAULT_IMPLEMENTATION;
+         override = false;
+      }
+
+      try
+      {
+         defaultImplementation = Class.forName(clz, 
+                                               true, 
+                                               SecurityActions.getClassLoader(ManagedConnectionPoolFactory.class));
+      }
+      catch (Throwable t)
+      {
+         throw new RuntimeException("Unable to load default managed connection pool implementation: " + clz);
+      }
+   }
+
+   /**
+    * Constructor
+    */
+   public ManagedConnectionPoolFactory()
+   {
+   }
+
+   /**
+    * Get the default implementation
+    * @return The value
+    */
+   public String getDefaultImplementation()
+   {
+      return defaultImplementation.getName();
+   }
+
+   /**
+    * Is override
+    * @return The value
+    */
+   public boolean isOverride()
+   {
+      return override;
+   }
+
+   /**
+    * Create a managed connection pool using the default implementation strategy
+    * 
+    * @param mcf the managed connection factory
+    * @param cm the connection manager
+    * @param subject the subject
+    * @param cri the connection request info
+    * @param pc the pool configuration
+    * @param p The pool
+    * @return The initialized managed connection pool
+    * @exception Throwable Thrown in case of an error
+    */
+   public ManagedConnectionPool create(ManagedConnectionFactory mcf, ConnectionManager cm, Subject subject,
+                                       ConnectionRequestInfo cri, PoolConfiguration pc, Pool p) 
+      throws Throwable
+   {
+      ManagedConnectionPool mcp = (ManagedConnectionPool)defaultImplementation.newInstance();
+      
+      return init(mcp, mcf, cm, subject, cri, pc, p);
+   }
+
+   /**
+    * Create a managed connection pool using a specific implementation strategy
+    * 
+    * @param strategy Fullt qualified class name for the managed connection pool strategy
+    * @param mcf the managed connection factory
+    * @param cm the connection manager
+    * @param subject the subject
+    * @param cri the connection request info
+    * @param pc the pool configuration
+    * @param p The pool
+    * @return The initialized managed connection pool
+    * @exception Throwable Thrown in case of an error
+    */
+   public ManagedConnectionPool create(String strategy, 
+                                       ManagedConnectionFactory mcf, ConnectionManager cm, Subject subject,
+                                       ConnectionRequestInfo cri, PoolConfiguration pc, Pool p)
+      throws Throwable
+   {
+      Class> clz = Class.forName(strategy, 
+                                   true, 
+                                   SecurityActions.getClassLoader(ManagedConnectionPoolFactory.class));
+      
+      ManagedConnectionPool mcp = (ManagedConnectionPool)clz.newInstance();
+      
+      return init(mcp, mcf, cm, subject, cri, pc, p);
+   }
+
+   /**
+    * Initialize
+    * @param mcp The managed connection pool
+    * @param mcf the managed connection factory
+    * @param cm the connection manager
+    * @param subject the subject
+    * @param cri the connection request info
+    * @param pc the pool configuration
+    * @param p The pool
+    * @return The initialized managed connection pool
+    */
+   private ManagedConnectionPool init(ManagedConnectionPool mcp, 
+                                      ManagedConnectionFactory mcf, ConnectionManager cm, Subject subject,
+                                      ConnectionRequestInfo cri, PoolConfiguration pc, Pool p)
+   {
+      mcp.initialize(mcf, cm, subject, cri, pc, p);
+
+      return mcp;
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/ManagedConnectionPoolUtility.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/ManagedConnectionPoolUtility.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/ManagedConnectionPoolUtility.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,219 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2011, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager.pool.mcp;
+
+import org.jboss.jca.core.api.connectionmanager.pool.PoolConfiguration;
+import org.jboss.jca.core.connectionmanager.ConnectionManager;
+import org.jboss.jca.core.connectionmanager.listener.ConnectionListener;
+import org.jboss.jca.core.connectionmanager.pool.PoolStatisticsImpl;
+import org.jboss.jca.core.connectionmanager.pool.api.Pool;
+
+import java.util.Collection;
+
+import javax.resource.spi.ConnectionRequestInfo;
+import javax.resource.spi.ManagedConnectionFactory;
+import javax.security.auth.Subject;
+
+/**
+ * Managed connection pool utility class
+ *
+ * @author Jesper Pedersen 
+ */
+class ManagedConnectionPoolUtility
+{
+   private static String newLine = SecurityActions.getSystemProperty("line.separator");
+
+   /**
+    * Get the full details of a managed connection pool state
+    * @param method The method identifier
+    * @param poolName The pool name
+    * @param inUse The in use count
+    * @param max The max
+    * @return The state
+    */
+   static String details(String method, String poolName, int inUse, int max)
+   {
+      StringBuilder sb = new StringBuilder(1024);
+
+      sb.append(poolName).append(": ");
+      sb.append(method).append(" ");
+      sb.append("[");
+      sb.append(Integer.toString(inUse));
+      sb.append("/");
+      sb.append(Integer.toString(max));
+      sb.append("]");
+
+      return sb.toString();
+   }
+
+   /**
+    * Get the full details of a managed connection pool state
+    * @param mcp The managed connection pool
+    * @param method The method identifier
+    * @param mcf The managed connection factory
+    * @param cm The connection manager
+    * @param pool The pool
+    * @param pc The pool configuration
+    * @param available The available connection listeners
+    * @param inUse The in-use connection listeners
+    * @param ps The statistics
+    * @param subject The subject
+    * @param cri The ConnectionRequestInfo
+    * @return The state
+    */
+   static String fullDetails(ManagedConnectionPool mcp, String method, ManagedConnectionFactory mcf,
+                             ConnectionManager cm, Pool pool, PoolConfiguration pc,
+                             Collection available, Collection inUse,
+                             PoolStatisticsImpl ps, Subject subject, ConnectionRequestInfo cri)
+   {
+      StringBuilder sb = new StringBuilder(1024);
+      long now = System.currentTimeMillis();
+
+      sb.append(method).append(newLine);
+      sb.append("Method: ").append(method).append(newLine);
+      sb.append("  Subject: ").append(subject == null ? "null" :
+                                      Integer.toHexString(System.identityHashCode(subject))).append(newLine);
+      sb.append("  CRI: ").append(cri == null ? "null" :
+                                  Integer.toHexString(System.identityHashCode(cri))).append(newLine);
+      sb.append("ManagedConnectionPool:").append(newLine);
+      sb.append("  Class: ").append(mcp.getClass().getName()).append(newLine);
+      sb.append("  Object: ").append(Integer.toHexString(System.identityHashCode(mcp))).append(newLine);
+      sb.append("ManagedConnectionFactory:").append(newLine);
+      sb.append("  Class: ").append(mcf.getClass().getName()).append(newLine);
+      sb.append("  Object: ").append(Integer.toHexString(System.identityHashCode(mcf))).append(newLine);
+      sb.append("ConnectionManager:").append(newLine);
+      sb.append("  Class: ").append(cm.getClass().getName()).append(newLine);
+      sb.append("  Object: ").append(Integer.toHexString(System.identityHashCode(cm))).append(newLine);
+      sb.append("Pool:").append(newLine);
+      sb.append("  Name: ").append(pool.getName()).append(newLine);
+      sb.append("  Class: ").append(pool.getClass().getName()).append(newLine);
+      sb.append("  Object: ").append(Integer.toHexString(System.identityHashCode(pool))).append(newLine);
+      sb.append("  FIFO: ").append(pool.isFIFO()).append(newLine);
+      sb.append("PoolConfiguration:").append(newLine);
+      sb.append("  MinSize: ").append(pc.getMinSize()).append(newLine);
+      sb.append("  InitialSize: ").append(pc.getInitialSize()).append(newLine);
+      sb.append("  MaxSize: ").append(pc.getMaxSize()).append(newLine);
+      sb.append("  BlockingTimeout: ").append(pc.getBlockingTimeout()).append(newLine);
+      sb.append("  IdleTimeoutMinutes: ").append(pc.getIdleTimeoutMinutes()).append(newLine);
+      sb.append("  ValidateOnMatch: ").append(pc.isValidateOnMatch()).append(newLine);
+      sb.append("  BackgroundValidation: ").append(pc.isBackgroundValidation()).append(newLine);
+      sb.append("  BackgroundValidationMillis: ").append(pc.getBackgroundValidationMillis()).append(newLine);
+      sb.append("  StrictMin: ").append(pc.isStrictMin()).append(newLine);
+      sb.append("  UseFastFail: ").append(pc.isUseFastFail()).append(newLine);
+      if (pool.getCapacity() != null)
+      {
+         if (pool.getCapacity().getIncrementer() != null)
+            sb.append("  Incrementer: ").append(pool.getCapacity().getIncrementer()).append(newLine);
+
+         if (pool.getCapacity().getDecrementer() != null)
+            sb.append("  Decrementer: ").append(pool.getCapacity().getDecrementer()).append(newLine);
+      }
+      
+      int availableSize = (available != null ? available.size() : 0);
+      sb.append("Available (").append(availableSize).append("):").append(newLine);
+      if (available != null)
+      {
+         for (ConnectionListener cl : available)
+         {
+            sb.append("  ").append(Integer.toHexString(System.identityHashCode(cl)));
+            sb.append(" (").append(cl.getState()).append(")");
+            sb.append(" (Returned: ").append(cl.getLastReturnedTime()).append(")");
+            sb.append(" (Validated: ").append(cl.getLastValidatedTime()).append(")");
+            sb.append(" (Pool: ").append(now - cl.getLastReturnedTime()).append(")").append(newLine);
+         }
+      }
+
+      int inUseSize = (inUse != null ? inUse.size() : 0);
+      sb.append("InUse (").append(inUseSize).append("):").append(newLine);
+      if (inUse != null)
+      {
+         for (ConnectionListener cl : inUse)
+         {
+            sb.append("  ").append(Integer.toHexString(System.identityHashCode(cl)));
+            sb.append(" (").append(cl.getState()).append(")");
+            sb.append(" (CheckedOut: ").append(cl.getLastCheckedOutTime()).append(")");
+            sb.append(" (Validated: ").append(cl.getLastValidatedTime()).append(")");
+            sb.append(" (Usage: ").append(now - cl.getLastCheckedOutTime()).append(")").append(newLine);
+         }
+      }
+
+      sb.append("Statistics:").append(newLine);
+      sb.append("  ActiveCount: ").append(ps.getActiveCount()).append(newLine);
+      sb.append("  AvailableCount: ").append(ps.getAvailableCount()).append(newLine);
+      sb.append("  AverageBlockingTime: ").append(ps.getAverageBlockingTime()).append(newLine);
+      sb.append("  AverageCreationTime: ").append(ps.getAverageCreationTime()).append(newLine);
+      sb.append("  AverageGetTime: ").append(ps.getAverageGetTime()).append(newLine);
+      sb.append("  AveragePoolTime: ").append(ps.getAveragePoolTime()).append(newLine);
+      sb.append("  AverageUsageTime: ").append(ps.getAverageUsageTime()).append(newLine);
+      sb.append("  BlockingFailureCount: ").append(ps.getBlockingFailureCount()).append(newLine);
+      sb.append("  CreatedCount: ").append(ps.getCreatedCount()).append(newLine);
+      sb.append("  DestroyedCount: ").append(ps.getDestroyedCount()).append(newLine);
+      sb.append("  IdleCount: ").append(ps.getIdleCount()).append(newLine);
+      sb.append("  InUseCount: ").append(ps.getInUseCount()).append(newLine);
+      sb.append("  MaxCreationTime: ").append(ps.getMaxCreationTime()).append(newLine);
+      sb.append("  MaxGetTime: ").append(ps.getMaxGetTime()).append(newLine);
+      sb.append("  MaxPoolTime: ").append(ps.getMaxPoolTime()).append(newLine);
+      sb.append("  MaxUsageTime: ").append(ps.getMaxUsageTime()).append(newLine);
+      sb.append("  MaxUsedCount: ").append(ps.getMaxUsedCount()).append(newLine);
+      sb.append("  MaxWaitTime: ").append(ps.getMaxWaitTime()).append(newLine);
+      sb.append("  TimedOut: ").append(ps.getTimedOut()).append(newLine);
+      sb.append("  TotalBlockingTime: ").append(ps.getTotalBlockingTime()).append(newLine);
+      sb.append("  TotalCreationTime: ").append(ps.getTotalCreationTime()).append(newLine);
+      sb.append("  TotalGetTime: ").append(ps.getTotalGetTime()).append(newLine);
+      sb.append("  TotalPoolTime: ").append(ps.getTotalPoolTime()).append(newLine);
+      sb.append("  TotalUsageTime: ").append(ps.getTotalUsageTime()).append(newLine);
+      sb.append("  WaitCount: ").append(ps.getWaitCount()).append(newLine);
+
+      sb.append("XAResource:").append(newLine);
+      sb.append("  CommitCount: ").append(ps.getCommitCount()).append(newLine);
+      sb.append("  CommitTotalTime: ").append(ps.getCommitTotalTime()).append(newLine);
+      sb.append("  CommitAverageTime: ").append(ps.getCommitAverageTime()).append(newLine);
+      sb.append("  CommitMaxTime: ").append(ps.getCommitMaxTime()).append(newLine);
+      sb.append("  EndCount: ").append(ps.getEndCount()).append(newLine);
+      sb.append("  EndTotalTime: ").append(ps.getEndTotalTime()).append(newLine);
+      sb.append("  EndAverageTime: ").append(ps.getEndAverageTime()).append(newLine);
+      sb.append("  EndMaxTime: ").append(ps.getEndMaxTime()).append(newLine);
+      sb.append("  ForgetCount: ").append(ps.getForgetCount()).append(newLine);
+      sb.append("  ForgetTotalTime: ").append(ps.getForgetTotalTime()).append(newLine);
+      sb.append("  ForgetAverageTime: ").append(ps.getForgetAverageTime()).append(newLine);
+      sb.append("  ForgetMaxTime: ").append(ps.getForgetMaxTime()).append(newLine);
+      sb.append("  PrepareCount: ").append(ps.getPrepareCount()).append(newLine);
+      sb.append("  PrepareTotalTime: ").append(ps.getPrepareTotalTime()).append(newLine);
+      sb.append("  PrepareAverageTime: ").append(ps.getPrepareAverageTime()).append(newLine);
+      sb.append("  PrepareMaxTime: ").append(ps.getPrepareMaxTime()).append(newLine);
+      sb.append("  RecoverCount: ").append(ps.getRecoverCount()).append(newLine);
+      sb.append("  RecoverTotalTime: ").append(ps.getRecoverTotalTime()).append(newLine);
+      sb.append("  RecoverAverageTime: ").append(ps.getRecoverAverageTime()).append(newLine);
+      sb.append("  RecoverMaxTime: ").append(ps.getRecoverMaxTime()).append(newLine);
+      sb.append("  RollbackCount: ").append(ps.getRollbackCount()).append(newLine);
+      sb.append("  RollbackTotalTime: ").append(ps.getRollbackTotalTime()).append(newLine);
+      sb.append("  RollbackAverageTime: ").append(ps.getRollbackAverageTime()).append(newLine);
+      sb.append("  RollbackMaxTime: ").append(ps.getRollbackMaxTime()).append(newLine);
+      sb.append("  StartCount: ").append(ps.getStartCount()).append(newLine);
+      sb.append("  StartTotalTime: ").append(ps.getStartTotalTime()).append(newLine);
+      sb.append("  StartAverageTime: ").append(ps.getStartAverageTime()).append(newLine);
+      sb.append("  StartMaxTime: ").append(ps.getStartMaxTime());
+
+      return sb.toString();
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/PoolFiller.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/PoolFiller.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/PoolFiller.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,139 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2006, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager.pool.mcp;
+
+import java.util.LinkedList;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * PoolFiller
+ * 
+ * @author David Jencks 
+ * @author Scott Stark 
+ * @author Adrian Brock 
+ * @author Gurkan Erdogdu 
+ * @author Jesper Pedersen 
+ */
+class PoolFiller implements Runnable
+{
+
+   /** Singleton instance */
+   private static final PoolFiller FILLER = new PoolFiller();
+
+   /** Pools list */
+   private final LinkedList pools = new LinkedList();
+
+   /** Filler thread */
+   private final Thread fillerThread;
+
+   /** Thread name */
+   private static final String THREAD_FILLER_NAME = "JCA PoolFiller";
+
+   /**Thread is configured or not*/
+   private AtomicBoolean threadStarted = new AtomicBoolean(false);
+
+   /**
+    * Fill given pool
+    * @param fr The fill request
+    */
+   static void fillPool(FillRequest fr)
+   {
+      FILLER.internalFillPool(fr);
+   }
+
+   /**
+    * Creates a new pool filler instance.
+    */
+   PoolFiller()
+   {
+      fillerThread = new Thread(this, THREAD_FILLER_NAME);
+      fillerThread.setDaemon(true);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void run()
+   {
+      final ClassLoader myClassLoader = SecurityActions.getClassLoader(getClass());
+      SecurityActions.setThreadContextClassLoader(myClassLoader);
+
+      while (true)
+      {
+         boolean empty = false;
+
+         while (!empty)
+         {
+            FillRequest fr = null;
+
+            synchronized (pools)
+            {
+               empty = pools.isEmpty();
+               if (!empty)
+                  fr = pools.removeFirst();
+            }
+
+            if (!empty)
+            {
+               fr.getManagedConnectionPool().fillTo(fr.getFillSize());
+            }
+         }
+
+         try 
+         {
+            synchronized (pools)
+            {
+               while (pools.isEmpty())
+               {
+                  pools.wait();                        
+               }
+            }
+         }
+         catch (InterruptedException ie)
+         {
+            Thread.currentThread().interrupt();
+            return;
+         }
+      }
+   }
+
+   /**
+    * Fill pool
+    * @param fr The fill request
+    */
+   private void internalFillPool(FillRequest fr)
+   {
+      if (this.threadStarted.compareAndSet(false, true))         
+      {
+         this.fillerThread.start();
+      }
+      
+      synchronized (pools)
+      {
+         if (!pools.contains(fr))
+         {
+            pools.addLast(fr);
+            pools.notifyAll();
+         }
+      }
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/SecurityActions.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/SecurityActions.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/SecurityActions.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,138 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2008, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors. 
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager.pool.mcp;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import javax.security.auth.Subject;
+
+/**
+ * Privileged Blocks
+ * 
+ * @author Gurkan Erdogdu 
+ */
+class SecurityActions
+{
+   /**
+    * Get the classloader.
+    * @param c The class
+    * @return The classloader
+    */
+   static ClassLoader getClassLoader(final Class> c)
+   {
+      if (System.getSecurityManager() == null)
+         return c.getClassLoader();
+
+      return AccessController.doPrivileged(new PrivilegedAction()
+      {
+         public ClassLoader run()
+         {
+            return c.getClassLoader();
+         }
+      });
+   }
+
+   /**
+    * Set the context classloader.
+    * @param cl classloader
+    */
+   public static void setThreadContextClassLoader(final ClassLoader cl)
+   {
+      if (System.getSecurityManager() == null)
+      {
+         Thread.currentThread().setContextClassLoader(cl);
+      }
+      else
+      {
+         AccessController.doPrivileged(new PrivilegedAction()
+         {
+            public Object run()
+            {
+               Thread.currentThread().setContextClassLoader(cl);
+
+               return null;
+            }
+         });
+      }
+   }
+
+   /**
+    * Get a system property
+    * @param name The property name
+    * @return The property value
+    */
+   static String getSystemProperty(final String name)
+   {
+      return AccessController.doPrivileged(new PrivilegedAction() 
+      {
+         public String run()
+         {
+            return System.getProperty(name);
+         }
+      });
+   }
+
+   /**
+    * Get the hash code for a Subject
+    * @param subject The Subject
+    * @return The hash code
+    */
+   static int hashCode(final Subject subject)
+   {
+      if (System.getSecurityManager() == null)
+         return subject.hashCode();
+
+      Integer hashCode = AccessController.doPrivileged(new PrivilegedAction() 
+      {
+         public Integer run()
+         {
+            return subject.hashCode();
+         }
+      });
+
+      return hashCode.intValue();
+   }
+
+   /**
+    * Verify if two Subject's are equal
+    * @param s1 The first Subject
+    * @param s2 The second Subject
+    * @return True if equal; otherwise false
+    */
+   static boolean equals(final Subject s1, final Subject s2)
+   {
+      if (System.getSecurityManager() == null)
+         return s1 != null ? s1.equals(s2) : s2 == null;
+
+      Boolean equals = AccessController.doPrivileged(new PrivilegedAction() 
+      {
+         public Boolean run()
+         {
+            return s1 != null ? s1.equals(s2) : s2 == null;
+         }
+      });
+
+      return equals.booleanValue();
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/SemaphoreArrayListManagedConnectionPool.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/SemaphoreArrayListManagedConnectionPool.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/SemaphoreArrayListManagedConnectionPool.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,1602 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2010, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager.pool.mcp;
+
+import org.jboss.jca.core.CoreBundle;
+import org.jboss.jca.core.CoreLogger;
+import org.jboss.jca.core.api.connectionmanager.pool.FlushMode;
+import org.jboss.jca.core.api.connectionmanager.pool.PoolConfiguration;
+import org.jboss.jca.core.connectionmanager.ConnectionManager;
+import org.jboss.jca.core.connectionmanager.listener.ConnectionListener;
+import org.jboss.jca.core.connectionmanager.listener.ConnectionState;
+import org.jboss.jca.core.connectionmanager.pool.api.CapacityDecrementer;
+import org.jboss.jca.core.connectionmanager.pool.api.Pool;
+import org.jboss.jca.core.connectionmanager.pool.api.PrefillPool;
+import org.jboss.jca.core.connectionmanager.pool.capacity.DefaultCapacity;
+import org.jboss.jca.core.connectionmanager.pool.capacity.TimedOutDecrementer;
+import org.jboss.jca.core.connectionmanager.pool.capacity.TimedOutFIFODecrementer;
+import org.jboss.jca.core.connectionmanager.pool.idle.IdleRemover;
+import org.jboss.jca.core.connectionmanager.pool.validator.ConnectionValidator;
+import org.jboss.jca.core.tracer.Tracer;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.TimeUnit;
+
+import javax.resource.ResourceException;
+import javax.resource.cci.Connection;
+import javax.resource.spi.ConnectionRequestInfo;
+import javax.resource.spi.DissociatableManagedConnection;
+import javax.resource.spi.ManagedConnection;
+import javax.resource.spi.ManagedConnectionFactory;
+import javax.resource.spi.RetryableException;
+import javax.resource.spi.ValidatingManagedConnectionFactory;
+import javax.security.auth.Subject;
+
+import org.jboss.logging.Messages;
+
+/**
+ * The internal pool implementation
+ *
+ * @author David Jencks 
+ * @author Adrian Brock 
+ * @author Weston Price 
+ * @author Jesper Pedersen 
+ */
+public class SemaphoreArrayListManagedConnectionPool implements ManagedConnectionPool
+{
+   /** The log */
+   private CoreLogger log;
+
+   /** Whether debug is enabled */
+   private boolean debug;
+
+   /** The bundle */
+   private static CoreBundle bundle = Messages.getBundle(CoreBundle.class);
+
+   /** The managed connection factory */
+   private ManagedConnectionFactory mcf;
+
+   /** The connection manager */
+   private ConnectionManager cm;
+
+   /** The default subject */
+   private Subject defaultSubject;
+
+   /** The default connection request information */
+   private ConnectionRequestInfo defaultCri;
+
+   /** The pool configuration */
+   private PoolConfiguration poolConfiguration;
+
+   /** The pool */
+   private Pool pool;
+
+   /** FIFO / FILO */
+   private boolean fifo;
+   
+   /**
+    * Copy of the maximum size from the pooling parameters.
+    * Dynamic changes to this value are not compatible with
+    * the semaphore which cannot change be dynamically changed.
+    */
+   private int maxSize;
+
+   /** The available connection event listeners */
+   private ArrayList cls;
+
+   /** The map of connection listeners which has a permit */
+   private final ConcurrentMap clPermits =
+      new ConcurrentHashMap();
+
+   /** The checked out connections */
+   private final ArrayList checkedOut = new ArrayList();
+
+   /** Supports lazy association */
+   private Boolean supportsLazyAssociation;
+
+   /** Last idle check */
+   private long lastIdleCheck;
+
+   /** Last used */
+   private long lastUsed;
+
+   /**
+    * Constructor
+    */
+   public SemaphoreArrayListManagedConnectionPool()
+   {
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void initialize(ManagedConnectionFactory mcf, ConnectionManager cm, Subject subject,
+                          ConnectionRequestInfo cri, PoolConfiguration pc, Pool p)
+   {
+      if (mcf == null)
+         throw new IllegalArgumentException("ManagedConnectionFactory is null");
+
+      if (cm == null)
+         throw new IllegalArgumentException("ConnectionManager is null");
+
+      if (pc == null)
+         throw new IllegalArgumentException("PoolConfiguration is null");
+
+      if (p == null)
+         throw new IllegalArgumentException("Pool is null");
+
+      this.mcf = mcf;
+      this.cm = cm;
+      this.defaultSubject = subject;
+      this.defaultCri = cri;
+      this.poolConfiguration = pc;
+      this.maxSize = pc.getMaxSize();
+      this.pool = p;
+      this.fifo = p.isFIFO();
+      this.log = pool.getLogger();
+      this.debug = log.isDebugEnabled();
+      this.cls = new ArrayList(this.maxSize);
+      this.supportsLazyAssociation = null;
+      this.lastIdleCheck = System.currentTimeMillis();
+      this.lastUsed = Long.MAX_VALUE;
+
+      // Schedule managed connection pool for prefill
+      if ((pc.isPrefill() || pc.isStrictMin()) && p instanceof PrefillPool && pc.getInitialSize() > 0)
+      {
+         PoolFiller.fillPool(new FillRequest(this, pc.getInitialSize()));
+      }
+
+      if (poolConfiguration.getIdleTimeoutMinutes() > 0)
+      {
+         //Register removal support
+         IdleRemover.getInstance().registerPool(this, poolConfiguration.getIdleTimeoutMinutes() * 1000L * 60);
+      }
+
+      if (poolConfiguration.isBackgroundValidation() && poolConfiguration.getBackgroundValidationMillis() > 0)
+      {
+         if (debug)
+            log.debug("Registering for background validation at interval " +
+                      poolConfiguration.getBackgroundValidationMillis());
+
+         //Register validation
+         ConnectionValidator.getInstance().registerPool(this, poolConfiguration.getBackgroundValidationMillis());
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getLastUsed()
+   {
+      return lastUsed;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean isRunning()
+   {
+      return !pool.isShutdown();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean isEmpty()
+   {
+      synchronized (cls)
+      {
+         return cls.size() == 0 && checkedOut.size() == 0;
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean isIdle()
+   {
+      synchronized (cls)
+      {
+         return checkedOut.size() == 0;
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public int getActive()
+   {
+      synchronized (cls)
+      {
+         return cls.size() + checkedOut.size();
+      }
+   }
+
+   /**
+    * Check if the pool has reached a certain size
+    * @param size The size
+    * @return True if reached; otherwise false
+    */
+   private boolean isSize(int size)
+   {
+      synchronized (cls)
+      {
+         return (cls.size() + checkedOut.size()) >= size;
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void prefill()
+   {
+      if (isRunning() &&
+          (poolConfiguration.isPrefill() || poolConfiguration.isStrictMin()) &&
+          pool instanceof PrefillPool &&
+          poolConfiguration.getMinSize() > 0)
+         PoolFiller.fillPool(new FillRequest(this, poolConfiguration.getMinSize()));
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public ConnectionListener getConnection(Subject subject, ConnectionRequestInfo cri) throws ResourceException
+   {
+
+      if (log.isTraceEnabled())
+      {
+         synchronized (cls)
+         {
+            String method = "getConnection(" + subject + ", " + cri + ")";
+            log.trace(ManagedConnectionPoolUtility.fullDetails(this, method,
+                                                               mcf, cm, pool, poolConfiguration,
+                                                               cls, checkedOut, pool.getInternalStatistics(),
+                                                               subject, cri));
+         }
+      }
+      else if (debug)
+      {
+         String method = "getConnection(" + subject + ", " + cri + ")";
+         log.debug(ManagedConnectionPoolUtility.details(method, pool.getName(),
+                                                        pool.getInternalStatistics().getInUseCount(), maxSize));
+      }
+
+      subject = (subject == null) ? defaultSubject : subject;
+      cri = (cri == null) ? defaultCri : cri;
+
+      if (pool.isFull())
+      {
+         if (pool.getInternalStatistics().isEnabled())
+            pool.getInternalStatistics().deltaWaitCount();
+
+         if (pool.isSharable() && (supportsLazyAssociation == null || supportsLazyAssociation.booleanValue()))
+         {
+            if (supportsLazyAssociation == null)
+               checkLazyAssociation();
+
+            if (supportsLazyAssociation != null && supportsLazyAssociation.booleanValue())
+            {
+               if (log.isTraceEnabled())
+                  log.tracef("Trying to detach - Pool: %s MCP: %s", pool.getName(),
+                             Integer.toHexString(System.identityHashCode(this)));
+
+               if (!detachConnectionListener())
+               {
+                  log.tracef("Detaching didn't succeed - Pool: %s MCP: %s", pool.getName(),
+                                Integer.toHexString(System.identityHashCode(this)));
+               }
+            }
+         }
+      }
+
+      long startWait = pool.getInternalStatistics().isEnabled() ? System.currentTimeMillis() : 0L;
+      try
+      {
+         if (pool.getLock().tryAcquire(poolConfiguration.getBlockingTimeout(), TimeUnit.MILLISECONDS))
+         {
+            if (pool.getInternalStatistics().isEnabled())
+               pool.getInternalStatistics().deltaTotalBlockingTime(System.currentTimeMillis() - startWait);
+
+            //We have a permit to get a connection. Is there one in the pool already?
+            ConnectionListener cl = null;
+            do
+            {
+               if (!isRunning())
+               {
+                  pool.getLock().release();
+                  throw new ResourceException(
+                     bundle.thePoolHasBeenShutdown(pool.getName(),
+                                                   Integer.toHexString(System.identityHashCode(this))));
+               }
+
+               synchronized (cls)
+               {
+                  if (cls.size() > 0)
+                  {
+                     if (fifo)
+                     {
+                        cl = cls.remove(0);
+                     }
+                     else
+                     {
+                        cl = cls.remove(cls.size() - 1);
+                     }
+                     checkedOut.add(cl);
+                  }
+               }
+
+               if (cl != null)
+               {
+                  //Yes, we retrieved a ManagedConnection from the pool. Does it match?
+                  try
+                  {
+                     Object matchedMC = mcf.matchManagedConnections(Collections.singleton(cl.getManagedConnection()),
+                                                                    subject, cri);
+
+                     boolean valid = true;
+                     if (matchedMC != null)
+                     {
+                        if (poolConfiguration.isValidateOnMatch())
+                        {
+                           if (mcf instanceof ValidatingManagedConnectionFactory)
+                           {
+                              try
+                              {
+                                 ValidatingManagedConnectionFactory vcf = (ValidatingManagedConnectionFactory) mcf;
+                                 Set candidateSet = Collections.singleton(cl.getManagedConnection());
+                                 candidateSet = vcf.getInvalidConnections(candidateSet);
+
+                                 if (candidateSet != null && candidateSet.size() > 0)
+                                 {
+                                    valid = false;
+                                 }
+                              }
+                              catch (Throwable t)
+                              {
+                                 valid = false;
+                                 if (log.isTraceEnabled())
+                                    log.trace("Exception while ValidateOnMatch: " + t.getMessage(), t);
+                              }
+                           }
+                           else
+                           {
+                              log.validateOnMatchNonCompliantManagedConnectionFactory(mcf.getClass().getName());
+                           }
+                        }
+
+                        if (valid)
+                        {
+                           log.tracef("supplying ManagedConnection from pool: %s", cl);
+
+                           clPermits.put(cl, cl);
+
+                           lastUsed = System.currentTimeMillis();
+                           cl.setLastCheckedOutTime(lastUsed);
+
+                           if (pool.getInternalStatistics().isEnabled())
+                           {
+                              pool.getInternalStatistics().deltaTotalGetTime(lastUsed - startWait);
+                              pool.getInternalStatistics().deltaTotalPoolTime(lastUsed - cl.getLastReturnedTime());
+                           }
+
+                           if (Tracer.isEnabled())
+                              Tracer.getConnectionListener(pool.getName(), this, cl, true, pool.isInterleaving(),
+                                                           Tracer.isRecordCallstacks() ?
+                                                           new Throwable("CALLSTACK") : null);
+
+                           return cl;
+                        }
+                     }
+
+                     // Match did not succeed but no exception was thrown.
+                     // Either we have the matching strategy wrong or the
+                     // connection died while being checked.  We need to
+                     // distinguish these cases, but for now we always
+                     // destroy the connection.
+                     if (valid)
+                     {
+                        log.destroyingConnectionNotSuccessfullyMatched(cl);
+                     }
+                     else
+                     {
+                        log.destroyingConnectionNotValidated(cl);
+                     }
+
+                     synchronized (cls)
+                     {
+                        checkedOut.remove(cl);
+                     }
+
+                     if (pool.getInternalStatistics().isEnabled())
+                        pool.getInternalStatistics().deltaTotalPoolTime(System.currentTimeMillis() -
+                                                                        cl.getLastReturnedTime());
+
+                     if (Tracer.isEnabled())
+                        Tracer.destroyConnectionListener(pool.getName(), this, cl, false, false, true, false, false,
+                                                         false, false,
+                                                         Tracer.isRecordCallstacks() ?
+                                                         new Throwable("CALLSTACK") : null);
+                     
+                     cl.destroy();
+                     cl = null;
+                  }
+                  catch (Throwable t)
+                  {
+                     log.throwableWhileTryingMatchManagedConnectionThenDestroyingConnection(cl, t);
+
+                     synchronized (cls)
+                     {
+                        checkedOut.remove(cl);
+                     }
+
+                     if (pool.getInternalStatistics().isEnabled())
+                        pool.getInternalStatistics().deltaTotalPoolTime(System.currentTimeMillis() -
+                                                                        cl.getLastReturnedTime());
+
+                     if (Tracer.isEnabled())
+                        Tracer.destroyConnectionListener(pool.getName(), this, cl, false, false, false, false, true,
+                                                         false, false,
+                                                         Tracer.isRecordCallstacks() ?
+                                                         new Throwable("CALLSTACK") : null);
+                     
+                     cl.destroy();
+                     cl = null;
+                  }
+
+                  // We made it here, something went wrong and we should validate
+                  // if we should continue attempting to acquire a connection
+                  if (poolConfiguration.isUseFastFail())
+                  {
+                     if (log.isTraceEnabled())
+                        log.trace("Fast failing for connection attempt. No more attempts will be made to " +
+                               "acquire connection from pool and a new connection will be created immeadiately");
+                     break;
+                  }
+
+               }
+            }
+            while (cls.size() > 0);
+
+            // OK, we couldnt find a working connection from the pool.  Make a new one.
+            try
+            {
+               // No, the pool was empty, so we have to make a new one.
+               cl = createConnectionEventListener(subject, cri);
+
+               if (Tracer.isEnabled())
+                  Tracer.createConnectionListener(pool.getName(), this, cl, cl.getManagedConnection(),
+                                                  true, false, false,
+                                                  Tracer.isRecordCallstacks() ?
+                                                  new Throwable("CALLSTACK") : null);
+
+               synchronized (cls)
+               {
+                  checkedOut.add(cl);
+               }
+
+               log.tracef("supplying new ManagedConnection: %s", cl);
+
+               clPermits.put(cl, cl);
+
+               lastUsed = System.currentTimeMillis();
+
+               if (pool.getInternalStatistics().isEnabled())
+                  pool.getInternalStatistics().deltaTotalGetTime(lastUsed - startWait);
+
+               // Trigger prefill
+               prefill();
+
+               // Trigger capacity increase
+               if (pool.getCapacity().getIncrementer() != null)
+                  CapacityFiller.schedule(new CapacityRequest(this, subject, cri));
+               
+               if (Tracer.isEnabled())
+                  Tracer.getConnectionListener(pool.getName(), this, cl, false, pool.isInterleaving(),
+                                               Tracer.isRecordCallstacks() ?
+                                               new Throwable("CALLSTACK") : null);
+
+               return cl;
+            }
+            catch (Throwable t)
+            {
+               if (cl != null || !(t instanceof RetryableException))
+                  log.throwableWhileAttemptingGetNewGonnection(cl, t);
+
+               if (cl != null)
+               {
+                  // Return permit and rethrow
+                  synchronized (cls)
+                  {
+                     checkedOut.remove(cl);
+                  }
+
+                  if (Tracer.isEnabled())
+                     Tracer.destroyConnectionListener(pool.getName(), this, cl, false, false, false, false, true,
+                                                      false, false,
+                                                      Tracer.isRecordCallstacks() ?
+                                                      new Throwable("CALLSTACK") : null);
+                     
+                  cl.destroy();
+               }
+
+               pool.getLock().release();
+
+               if (t instanceof ResourceException)
+               {
+                  throw (ResourceException)t;
+               }
+               else
+               {
+                  throw new ResourceException(bundle.unexpectedThrowableWhileTryingCreateConnection(cl), t);
+               }
+            }
+         }
+         else
+         {
+            if (pool.getInternalStatistics().isEnabled())
+               pool.getInternalStatistics().deltaBlockingFailureCount();
+
+            // We timed out
+            throw new ResourceException(bundle.noMManagedConnectionsAvailableWithinConfiguredBlockingTimeout(
+                  poolConfiguration.getBlockingTimeout()));
+         }
+
+      }
+      catch (InterruptedException ie)
+      {
+         Thread.interrupted();
+
+         long end = pool.getInternalStatistics().isEnabled() ? (System.currentTimeMillis() - startWait) : 0L;
+         pool.getInternalStatistics().deltaTotalBlockingTime(end);
+         throw new ResourceException(bundle.interruptedWhileRequestingPermit(end));
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public ConnectionListener findConnectionListener(ManagedConnection mc)
+   {
+      return findConnectionListener(mc, null);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public ConnectionListener findConnectionListener(ManagedConnection mc, Object connection)
+   {
+      synchronized (cls)
+      {
+         for (ConnectionListener cl : checkedOut)
+         {
+            if (cl.controls(mc, connection))
+               return cl;
+         }
+      }
+
+      return null;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void addConnectionListener(ConnectionListener cl)
+   {
+      synchronized (cls)
+      {
+         cls.add(cl);
+      }
+      
+      if (pool.getInternalStatistics().isEnabled())
+         pool.getInternalStatistics().deltaCreatedCount();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public ConnectionListener removeConnectionListener()
+   {
+      synchronized (cls)
+      {
+         if (cls.size() > 0)
+         {
+            if (pool.getInternalStatistics().isEnabled())
+               pool.getInternalStatistics().deltaDestroyedCount();
+            return cls.remove(0);
+         }
+      }
+
+      return null;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void returnConnection(ConnectionListener cl, boolean kill)
+   {
+      returnConnection(cl, kill, true);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void returnConnection(ConnectionListener cl, boolean kill, boolean cleanup)
+   {
+      if (pool.getInternalStatistics().isEnabled() && cl.getState() != ConnectionState.DESTROYED)
+         pool.getInternalStatistics().deltaTotalUsageTime(System.currentTimeMillis() - cl.getLastCheckedOutTime());
+
+      if (log.isTraceEnabled())
+      {
+         synchronized (cls)
+         {
+            String method = "returnConnection(" + Integer.toHexString(System.identityHashCode(cl)) + ", " + kill + ")";
+            log.trace(ManagedConnectionPoolUtility.fullDetails(this, method,
+                                                               mcf, cm, pool, poolConfiguration,
+                                                               cls, checkedOut, pool.getInternalStatistics(),
+                                                               defaultSubject, defaultCri));
+         }
+      }
+      else if (debug)
+      {
+         String method = "returnConnection(" + Integer.toHexString(System.identityHashCode(cl)) + ", " + kill + ")";
+         log.debug(ManagedConnectionPoolUtility.details(method, pool.getName(),
+                                                        pool.getInternalStatistics().getInUseCount(), maxSize));
+      }
+
+      if (cl.getState() == ConnectionState.DESTROYED)
+      {
+         log.tracef("ManagedConnection is being returned after it was destroyed: %s", cl);
+
+         ConnectionListener present = clPermits.remove(cl);
+         if (present != null)
+         {
+            pool.getLock().release();
+         }
+
+         return;
+      }
+
+      if (cleanup)
+      {
+         try
+         {
+            cl.getManagedConnection().cleanup();
+         }
+         catch (ResourceException re)
+         {
+            log.resourceExceptionCleaningUpManagedConnection(cl, re);
+            kill = true;
+         }
+      }
+
+      // We need to destroy this one
+      if (cl.getState() == ConnectionState.DESTROY || cl.getState() == ConnectionState.DESTROYED)
+         kill = true;
+
+      // This is really an error
+      if (!kill && isSize(poolConfiguration.getMaxSize() + 1))
+      {
+         log.destroyingReturnedConnectionMaximumPoolSizeExceeded(cl);
+         kill = true;
+      }
+
+      // If we are destroying, check the connection is not in the pool
+      if (kill)
+      {
+         synchronized (cls)
+         {
+            // Adrian Brock: A resource adapter can asynchronously notify us that
+            // a connection error occurred.
+            // This could happen while the connection is not checked out.
+            // e.g. JMS can do this via an ExceptionListener on the connection.
+            // I have twice had to reinstate this line of code, PLEASE DO NOT REMOVE IT!
+            checkedOut.remove(cl);
+            cls.remove(cl);
+
+            if (clPermits.remove(cl) != null)
+            {
+               pool.getLock().release();
+            }
+         }
+      }
+      // return to the pool
+      else
+      {
+         cl.toPool();
+         synchronized (cls)
+         {
+            checkedOut.remove(cl);
+            if (!cls.contains(cl))
+            {
+               cls.add(cl);
+            }
+            else
+            {
+               log.attemptReturnConnectionTwice(cl, new Throwable("STACKTRACE"));
+            }
+
+            if (clPermits.remove(cl) != null)
+            {
+               pool.getLock().release();
+            }
+         }
+      }
+
+      if (kill)
+      {
+         log.tracef("Destroying returned connection %s", cl);
+
+         if (Tracer.isEnabled())
+            Tracer.destroyConnectionListener(pool.getName(), this, cl, true, false, false, false, false,
+                                             false, false,
+                                             Tracer.isRecordCallstacks() ?
+                                             new Throwable("CALLSTACK") : null);
+                     
+         cl.destroy();
+         cl = null;
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void flush(FlushMode mode, Collection toDestroy)
+   {
+      ArrayList keep = null;
+
+      synchronized (cls)
+      {
+         if (FlushMode.ALL == mode)
+         {
+            log.tracef("Flushing pool checkedOut=%s inPool=%s", checkedOut, cls);
+
+            // Mark checked out connections as requiring destruction
+            while (checkedOut.size() > 0)
+            {
+               ConnectionListener cl = checkedOut.remove(0);
+
+               log.tracef("Flush marking checked out connection for destruction %s", cl);
+
+               cl.setState(ConnectionState.DESTROY);
+
+               if (pool.getInternalStatistics().isEnabled())
+                  pool.getInternalStatistics().deltaTotalUsageTime(System.currentTimeMillis() -
+                                                                   cl.getLastCheckedOutTime());
+
+               toDestroy.add(cl);
+
+               ConnectionListener present = clPermits.remove(cl);
+               if (present != null)
+               {
+                  pool.getLock().release();
+               }
+            }
+         }
+         else if (FlushMode.GRACEFULLY == mode)
+         {
+            log.tracef("Gracefully flushing pool checkedOut=%s inPool=%s", checkedOut , cls);
+
+            // Mark checked out connections as requiring destruction upon return
+            for (ConnectionListener cl : checkedOut)
+            {
+               log.tracef("Graceful flush marking checked out connection for destruction %s", cl);
+
+               cl.setState(ConnectionState.DESTROY);
+            }
+         }
+
+         // Destroy connections in the pool
+         while (cls.size() > 0)
+         {
+            ConnectionListener cl = cls.remove(0);
+            boolean kill = true;
+
+            if (FlushMode.INVALID == mode && cl.getState().equals(ConnectionState.NORMAL))
+            {
+               if (mcf instanceof ValidatingManagedConnectionFactory)
+               {
+                  try
+                  {
+                     ValidatingManagedConnectionFactory vcf = (ValidatingManagedConnectionFactory) mcf;
+                     Set candidateSet = Collections.singleton(cl.getManagedConnection());
+                     candidateSet = vcf.getInvalidConnections(candidateSet);
+
+                     if (candidateSet == null || candidateSet.size() == 0)
+                     {
+                        kill = false;
+                     }
+                  }
+                  catch (Throwable t)
+                  {
+                     log.trace("Exception during invalid flush", t);
+                  }
+               }
+            }
+
+            if (kill)
+            {
+               if (pool.getInternalStatistics().isEnabled())
+                  pool.getInternalStatistics().deltaTotalPoolTime(System.currentTimeMillis() -
+                                                                  cl.getLastReturnedTime());
+
+               cl.setState(ConnectionState.DESTROY);
+               toDestroy.add(cl);
+            }
+            else
+            {
+               if (keep == null)
+                  keep = new ArrayList(1);
+
+               keep.add(cl);
+            }
+         }
+
+         if (keep != null)
+            cls.addAll(keep);
+      }
+
+      // Trigger prefill
+      prefill();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void removeIdleConnections()
+   {
+      long now = System.currentTimeMillis();
+      long timeoutSetting = poolConfiguration.getIdleTimeoutMinutes() * 1000L * 60;
+
+      CapacityDecrementer decrementer = pool.getCapacity().getDecrementer();
+
+      if (decrementer == null)
+         decrementer = DefaultCapacity.DEFAULT_DECREMENTER;
+
+      if (TimedOutDecrementer.class.getName().equals(decrementer.getClass().getName()) ||
+          TimedOutFIFODecrementer.class.getName().equals(decrementer.getClass().getName()))
+      {
+         // Allow through each minute
+         if (now < (lastIdleCheck + 60000L))
+            return;
+      }
+      else
+      {
+         // Otherwise, strict check
+         if (now < (lastIdleCheck + timeoutSetting))
+            return;
+      }
+
+      lastIdleCheck = now;
+
+      ArrayList destroyConnections = new ArrayList();
+      long timeout = now - timeoutSetting;
+
+      boolean destroy = true;
+      int destroyed = 0;
+
+      if (log.isTraceEnabled())
+      {
+         synchronized (cls)
+         {
+            String method = "removeIdleConnections(" + timeout + ")";
+            log.trace(ManagedConnectionPoolUtility.fullDetails(this, method,
+                                                               mcf, cm, pool, poolConfiguration,
+                                                               cls, checkedOut, pool.getInternalStatistics(),
+                                                               defaultSubject, defaultCri));
+         }
+      }
+      else if (debug)
+      {
+         String method = "removeIdleConnections(" + timeout + ")";
+         log.debug(ManagedConnectionPoolUtility.details(method, pool.getName(),
+                                                        pool.getInternalStatistics().getInUseCount(), maxSize));
+      }
+
+      while (destroy)
+      {
+         synchronized (cls)
+         {
+            // No free connection listeners
+            if (cls.size() == 0)
+               break;
+
+            // We always check the first connection listener, since it is the oldest
+            ConnectionListener cl = cls.get(0);
+
+            destroy = decrementer.shouldDestroy(cl, timeout,
+                                                cls.size() + checkedOut.size(),
+                                                poolConfiguration.getMinSize(),
+                                                destroyed);
+
+            if (destroy)
+            {
+               if (shouldRemove() || !isRunning())
+               {
+                  if (pool.getInternalStatistics().isEnabled())
+                     pool.getInternalStatistics().deltaTimedOut();
+
+                  log.tracef("Idle connection cl=%s", cl);
+
+                  // We need to destroy this one
+                  cls.remove(0);
+                  destroyConnections.add(cl);
+                  destroyed++;
+               }
+               else
+               {
+                  destroy = false;
+               }
+            }
+         }
+      }
+
+      // We found some connections to destroy
+      if (destroyConnections.size() > 0 || isEmpty())
+      {
+         for (ConnectionListener cl : destroyConnections)
+         {
+            log.tracef("Destroying connection %s", cl);
+
+            if (pool.getInternalStatistics().isEnabled())
+               pool.getInternalStatistics().deltaTotalPoolTime(System.currentTimeMillis() -
+                                                               cl.getLastReturnedTime());
+
+            if (Tracer.isEnabled())
+               Tracer.destroyConnectionListener(pool.getName(), this, cl, false, true, false, false, false,
+                                                false, false,
+                                                Tracer.isRecordCallstacks() ?
+                                                new Throwable("CALLSTACK") : null);
+                     
+            cl.destroy();
+            cl = null;
+         }
+
+         if (isRunning())
+         {
+            // Let prefill and use-strict-min be the same
+            boolean emptyManagedConnectionPool = false;
+
+            if ((poolConfiguration.isPrefill() || poolConfiguration.isStrictMin()) && pool instanceof PrefillPool)
+            {
+               if (poolConfiguration.getMinSize() > 0)
+               {
+                  prefill();
+               }
+               else
+               {
+                  emptyManagedConnectionPool = true;
+               }
+            }
+            else
+            {
+               emptyManagedConnectionPool = true;
+            }
+
+            // Empty pool
+            if (emptyManagedConnectionPool && isEmpty())
+               pool.emptyManagedConnectionPool(this);
+         }
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void shutdown()
+   {
+      final Collection toDestroy;
+      synchronized (this)
+      {
+         if (log.isTraceEnabled())
+            log.tracef("Shutdown - Pool: %s MCP: %s", pool.getName(), Integer.toHexString(System.identityHashCode(
+                  this)));
+
+         IdleRemover.getInstance().unregisterPool(this);
+         ConnectionValidator.getInstance().unregisterPool(this);
+
+         if (checkedOut.size() > 0)
+         {
+            for (ConnectionListener cl : checkedOut)
+            {
+               log.destroyingActiveConnection(pool.getName(), cl.getManagedConnection());
+
+               if (Tracer.isEnabled())
+                  Tracer.clearConnectionListener(pool.getName(), this, cl);
+            }
+         }
+
+         toDestroy = new ArrayList();
+         flush(FlushMode.ALL, toDestroy);
+      }
+      for (ConnectionListener cl : toDestroy)
+      {
+         cl.destroy();
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void fillTo(int size)
+   {
+      if (size <= 0)
+         return;
+
+      if (!(poolConfiguration.isPrefill() || poolConfiguration.isStrictMin()))
+         return;
+
+      if (!(pool instanceof PrefillPool))
+         return;
+
+      if (log.isTraceEnabled())
+      {
+         synchronized (cls)
+         {
+            String method = "fillTo(" + size + ")";
+            log.trace(ManagedConnectionPoolUtility.fullDetails(this, method,
+                                                               mcf, cm, pool, poolConfiguration,
+                                                               cls, checkedOut, pool.getInternalStatistics(),
+                                                               defaultSubject, defaultCri));
+         }
+      }
+      else if (debug)
+      {
+         String method = "fillTo(" + size + ")";
+         log.debug(ManagedConnectionPoolUtility.details(method, pool.getName(),
+                                                        pool.getInternalStatistics().getInUseCount(), maxSize));
+      }
+
+      while (!pool.isFull())
+      {
+         // Get a permit - avoids a race when the pool is nearly full
+         // Also avoids unnessary fill checking when all connections are checked out
+         try
+         {
+            long startWait = pool.getInternalStatistics().isEnabled() ? System.currentTimeMillis() : 0L;
+            if (pool.getLock().tryAcquire(poolConfiguration.getBlockingTimeout(), TimeUnit.MILLISECONDS))
+            {
+               if (pool.getInternalStatistics().isEnabled())
+                  pool.getInternalStatistics().deltaTotalBlockingTime(System.currentTimeMillis() - startWait);
+               try
+               {
+                  if (!isRunning())
+                  {
+                     return;
+                  }
+
+                  // We already have enough connections
+                  if (isSize(size))
+                  {
+                     return;
+                  }
+
+                  // Create a connection to fill the pool
+                  try
+                  {
+                     ConnectionListener cl = createConnectionEventListener(defaultSubject, defaultCri);
+
+                     if (Tracer.isEnabled())
+                        Tracer.createConnectionListener(pool.getName(), this, cl, cl.getManagedConnection(),
+                                                        false, true, false,
+                                                        Tracer.isRecordCallstacks() ?
+                                                        new Throwable("CALLSTACK") : null);
+
+                     boolean added = false;
+                     synchronized (cls)
+                     {
+                        if (!isSize(size))
+                        {
+                           log.tracef("Filling pool cl=%s", cl);
+
+                           cls.add(cl);
+                           added = true;
+                        }
+                     }
+
+                     if (!added)
+                     {
+                        if (Tracer.isEnabled())
+                           Tracer.destroyConnectionListener(pool.getName(), this, cl, false, false, false, false,
+                                                            false, true, false,
+                                                            Tracer.isRecordCallstacks() ?
+                                                            new Throwable("CALLSTACK") : null);
+                     
+                        cl.destroy();
+                        return;
+                     }
+                  }
+                  catch (ResourceException re)
+                  {
+                     log.unableFillPool(re, cm.getJndiName());
+                     return;
+                  }
+               }
+               finally
+               {
+                  pool.getLock().release();
+               }
+            }
+         }
+         catch (InterruptedException ignored)
+         {
+            Thread.interrupted();
+
+            log.trace("Interrupted while requesting permit in fillTo");
+         }
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void increaseCapacity(Subject subject, ConnectionRequestInfo cri)
+   {
+      // We have already created one connection when this method is scheduled
+      int created = 1;
+      boolean create = true;
+
+      while (create && !pool.isFull())
+      {
+         try
+         {
+            long startWait = pool.getInternalStatistics().isEnabled() ? System.currentTimeMillis() : 0L;
+            if (pool.getLock().tryAcquire(poolConfiguration.getBlockingTimeout(), TimeUnit.MILLISECONDS))
+            {
+               if (pool.getInternalStatistics().isEnabled())
+                  pool.getInternalStatistics().deltaTotalBlockingTime(System.currentTimeMillis() - startWait);
+               try
+               {
+                  if (!isRunning())
+                  {
+                     return;
+                  }
+
+                  int currentSize = 0;
+                  synchronized (cls)
+                  {
+                     currentSize = cls.size() + checkedOut.size();
+                  }
+
+                  create = pool.getCapacity().getIncrementer().shouldCreate(currentSize,
+                                                                            poolConfiguration.getMaxSize(), created);
+
+                  if (create)
+                  {
+                     try
+                     {
+                        ConnectionListener cl = createConnectionEventListener(subject, cri);
+
+                        if (Tracer.isEnabled())
+                           Tracer.createConnectionListener(pool.getName(), this, cl, cl.getManagedConnection(),
+                                                           false, false, true,
+                                                           Tracer.isRecordCallstacks() ?
+                                                           new Throwable("CALLSTACK") : null);
+
+                        boolean added = false;
+                        synchronized (cls)
+                        {
+                           if (!isSize(poolConfiguration.getMaxSize()))
+                           {
+                              log.tracef("Capacity fill: cl=%s", cl);
+
+                              cls.add(cl);
+                              created++;
+                              added = true;
+                           }
+                        }
+
+                        if (!added)
+                        {
+                           if (Tracer.isEnabled())
+                              Tracer.destroyConnectionListener(pool.getName(), this, cl, false, false, true, false,
+                                                               false, false, true,
+                                                               Tracer.isRecordCallstacks() ?
+                                                               new Throwable("CALLSTACK") : null);
+                     
+                           cl.destroy();
+                           return;
+                        }
+                     }
+                     catch (ResourceException re)
+                     {
+                        log.unableFillPool(re, cm.getJndiName());
+                        return;
+                     }
+                  }
+               }
+               finally
+               {
+                  pool.getLock().release();
+               }
+            }
+         }
+         catch (InterruptedException ignored)
+         {
+            Thread.interrupted();
+
+            log.trace("Interrupted while requesting permit in increaseCapacity");
+         }
+      }
+   }
+
+   /**
+    * Create a connection event listener
+    *
+    * @param subject the subject
+    * @param cri the connection request information
+    * @return the new listener
+    * @throws ResourceException for any error
+    */
+   private ConnectionListener createConnectionEventListener(Subject subject, ConnectionRequestInfo cri)
+      throws ResourceException
+   {
+      long start = pool.getInternalStatistics().isEnabled() ? System.currentTimeMillis() : 0L;
+
+      ManagedConnection mc = mcf.createManagedConnection(subject, cri);
+
+      if (pool.getInternalStatistics().isEnabled())
+      {
+         pool.getInternalStatistics().deltaTotalCreationTime(System.currentTimeMillis() - start);
+         pool.getInternalStatistics().deltaCreatedCount();
+      }
+      try
+      {
+         return cm.createConnectionListener(mc, this);
+      }
+      catch (ResourceException re)
+      {
+         if (pool.getInternalStatistics().isEnabled())
+            pool.getInternalStatistics().deltaDestroyedCount();
+         mc.destroy();
+         throw re;
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void connectionListenerDestroyed(ConnectionListener cl)
+   {
+      if (pool.getInternalStatistics().isEnabled())
+         pool.getInternalStatistics().deltaDestroyedCount();
+   }
+
+   /**
+    * Should any connections be removed from the pool
+    * @return True if connections should be removed; otherwise false
+    */
+   private boolean shouldRemove()
+   {
+      boolean remove = true;
+
+      if (poolConfiguration.isStrictMin() && pool instanceof PrefillPool)
+      {
+         // Add 1 to min-pool-size since it is strict
+         remove = isSize(poolConfiguration.getMinSize() + 1);
+
+         log.tracef("StrictMin is active. Current connection will be removed is %b", remove);
+      }
+
+      return remove;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void validateConnections() throws Exception
+   {
+
+      if (log.isTraceEnabled())
+      {
+         log.tracef("Attempting to  validate connections for pool %s", this);
+         synchronized (cls)
+         {
+            String method = "validateConnections()";
+            log.trace(ManagedConnectionPoolUtility.fullDetails(this, method,
+                                                               mcf, cm, pool, poolConfiguration,
+                                                               cls, checkedOut, pool.getInternalStatistics(),
+                                                               defaultSubject, defaultCri));
+         }
+      }
+      else if (debug)
+      {
+         String method = "validateConnections()";
+         log.debug(ManagedConnectionPoolUtility.details(method, pool.getName(),
+                                                        pool.getInternalStatistics().getInUseCount(), maxSize));
+      }
+
+      if (pool.getLock().tryAcquire(poolConfiguration.getBlockingTimeout(), TimeUnit.MILLISECONDS))
+      {
+         boolean anyDestroyed = false;
+
+         try
+         {
+            while (true)
+            {
+               ConnectionListener cl = null;
+               boolean destroyed = false;
+
+               synchronized (cls)
+               {
+                  if (cls.size() == 0)
+                  {
+                     break;
+                  }
+
+                  cl = removeForFrequencyCheck();
+               }
+
+               if (cl == null)
+               {
+                  break;
+               }
+
+               try
+               {
+                  Set candidateSet = Collections.singleton(cl.getManagedConnection());
+
+                  if (mcf instanceof ValidatingManagedConnectionFactory)
+                  {
+                     ValidatingManagedConnectionFactory vcf = (ValidatingManagedConnectionFactory) mcf;
+                     candidateSet = vcf.getInvalidConnections(candidateSet);
+
+                     if ((candidateSet != null && candidateSet.size() > 0) || !isRunning())
+                     {
+                        if (cl.getState() != ConnectionState.DESTROY)
+                        {
+                           if (pool.getInternalStatistics().isEnabled())
+                              pool.getInternalStatistics().deltaTotalPoolTime(System.currentTimeMillis() -
+                                                                              cl.getLastReturnedTime());
+
+                           if (Tracer.isEnabled())
+                              Tracer.destroyConnectionListener(pool.getName(), this, cl, false, false, true,
+                                                               false, false, false, false,
+                                                               Tracer.isRecordCallstacks() ?
+                                                               new Throwable("CALLSTACK") : null);
+                     
+                           cl.destroy();
+                           cl = null;
+                           destroyed = true;
+                           anyDestroyed = true;
+                        }
+                     }
+                  }
+                  else
+                  {
+                     log.backgroundValidationNonCompliantManagedConnectionFactory();
+                  }
+               }
+               catch (ResourceException re)
+               {
+                  if (cl != null)
+                  {
+                     if (pool.getInternalStatistics().isEnabled())
+                        pool.getInternalStatistics().deltaTotalPoolTime(System.currentTimeMillis() -
+                                                                        cl.getLastReturnedTime());
+
+                     if (Tracer.isEnabled())
+                        Tracer.destroyConnectionListener(pool.getName(), this, cl, false, false, false,
+                                                         false, true, false, false,
+                                                         Tracer.isRecordCallstacks() ?
+                                                         new Throwable("CALLSTACK") : null);
+                     
+                     cl.destroy();
+                     cl = null;
+                     destroyed = true;
+                     anyDestroyed = true;
+                  }
+
+                  log.connectionValidatorIgnoredUnexpectedError(re);
+               }
+               finally
+               {
+                  if (!destroyed)
+                  {
+                     synchronized (cls)
+                     {
+                        returnForFrequencyCheck(cl);
+                     }
+                  }
+               }
+            }
+         }
+         finally
+         {
+            pool.getLock().release();
+
+            if (anyDestroyed)
+               prefill();
+         }
+      }
+   }
+
+   /**
+    * Get the pool name
+    * @return The value
+    */
+   String getPoolName()
+   {
+      if (pool == null)
+         return "";
+
+      return pool.getName();
+   }
+
+   /**
+    * Returns the connection listener that should be removed due to background validation
+    * @return The listener; otherwise null if none should be removed
+    */
+   private ConnectionListener removeForFrequencyCheck()
+   {
+      ConnectionListener cl = null;
+
+      for (Iterator iter = cls.iterator(); iter.hasNext();)
+      {
+         cl = iter.next();
+         long lastCheck = cl.getLastValidatedTime();
+
+         if ((System.currentTimeMillis() - lastCheck) >= poolConfiguration.getBackgroundValidationMillis())
+         {
+            cls.remove(cl);
+            break;
+         }
+         else
+         {
+            cl = null;
+         }
+      }
+
+      if (debug)
+         log.debugf("Checking for connection within frequency: %s", cl);
+
+      return cl;
+   }
+
+   /**
+    * Return a connection listener to the pool and update its validation timestamp
+    * @param cl The listener
+    */
+   private void returnForFrequencyCheck(ConnectionListener cl)
+   {
+      if (debug)
+         log.debugf("Returning for connection within frequency: %s", cl);
+
+      cl.setLastValidatedTime(System.currentTimeMillis());
+      cls.add(cl);
+   }
+
+   /**
+    * Check if the resource adapter supports lazy association
+    */
+   private void checkLazyAssociation()
+   {
+      synchronized (cls)
+      {
+         ConnectionListener cl = null;
+
+         if (checkedOut.size() > 0)
+            cl = checkedOut.get(0);
+
+         if (cl == null && cls.size() > 0)
+            cl = cls.get(0);
+
+         if (cl != null)
+         {
+            if (cl.supportsLazyAssociation())
+            {
+               if (debug)
+                  log.debug("Enable lazy association support for: " + pool.getName());
+
+               supportsLazyAssociation = Boolean.TRUE;
+            }
+            else
+            {
+               if (debug)
+                  log.debug("Disable lazy association support for: " + pool.getName());
+
+               supportsLazyAssociation = Boolean.FALSE;
+            }
+         }
+      }
+   }
+
+   /**
+    * Detach connection listener
+    * @return The outcome
+    */
+   private boolean detachConnectionListener()
+   {
+      synchronized (cls)
+      {
+         ConnectionListener cl = null;
+         try
+         {
+            Iterator it = checkedOut.iterator();
+            while (it.hasNext())
+            {
+               cl = it.next();
+               if (!cl.isEnlisted() && cl.getManagedConnection() instanceof DissociatableManagedConnection)
+               {
+                  log.tracef("Detach: %s", cl);
+
+                  DissociatableManagedConnection dmc = (DissociatableManagedConnection)cl.getManagedConnection();
+                  dmc.dissociateConnections();
+
+                  cl.unregisterConnections();
+
+                  if (Tracer.isEnabled())
+                     Tracer.returnConnectionListener(pool.getName(), this, cl, false, pool.isInterleaving(),
+                                                     Tracer.isRecordCallstacks() ?
+                                                     new Throwable("CALLSTACK") : null);
+
+                  returnConnection(cl, false, false);
+
+                  return true;
+               }
+            }
+         }
+         catch (Throwable t)
+         {
+            // Ok - didn't work; nuke it and disable
+            if (debug)
+               log.debug("Exception during detach for: " + pool.getName(), t);
+
+            supportsLazyAssociation = Boolean.FALSE;
+
+            if (cl != null)
+            {
+               if (Tracer.isEnabled())
+                  Tracer.returnConnectionListener(pool.getName(), this, cl, true, pool.isInterleaving(),
+                                                  Tracer.isRecordCallstacks() ?
+                                                  new Throwable("CALLSTACK") : null);
+
+               returnConnection(cl, true, true);
+            }
+         }
+      }
+
+      return false;
+   }
+
+   /**
+    * String representation
+    * @return The string
+    */
+   @Override
+   public String toString()
+   {
+      StringBuilder sb = new StringBuilder();
+
+      sb.append("SemaphoreArrayListManagedConnectionPool@").append(Integer.toHexString(System.identityHashCode(this)));
+      sb.append("[pool=").append(pool.getName());
+      sb.append("]");
+
+      return sb.toString();
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/SemaphoreConcurrentLinkedDequeManagedConnectionPool.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/SemaphoreConcurrentLinkedDequeManagedConnectionPool.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/SemaphoreConcurrentLinkedDequeManagedConnectionPool.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,1788 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2015, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager.pool.mcp;
+
+import org.jboss.jca.core.CoreBundle;
+import org.jboss.jca.core.CoreLogger;
+import org.jboss.jca.core.api.connectionmanager.pool.FlushMode;
+import org.jboss.jca.core.api.connectionmanager.pool.PoolConfiguration;
+import org.jboss.jca.core.connectionmanager.ConnectionManager;
+import org.jboss.jca.core.connectionmanager.listener.ConnectionListener;
+import org.jboss.jca.core.connectionmanager.listener.ConnectionState;
+import org.jboss.jca.core.connectionmanager.pool.api.CapacityDecrementer;
+import org.jboss.jca.core.connectionmanager.pool.api.Pool;
+import org.jboss.jca.core.connectionmanager.pool.api.PrefillPool;
+import org.jboss.jca.core.connectionmanager.pool.capacity.DefaultCapacity;
+import org.jboss.jca.core.connectionmanager.pool.capacity.TimedOutDecrementer;
+import org.jboss.jca.core.connectionmanager.pool.capacity.TimedOutFIFODecrementer;
+import org.jboss.jca.core.connectionmanager.pool.idle.IdleRemover;
+import org.jboss.jca.core.connectionmanager.pool.validator.ConnectionValidator;
+import org.jboss.jca.core.tracer.Tracer;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.ConnectionRequestInfo;
+import javax.resource.spi.DissociatableManagedConnection;
+import javax.resource.spi.ManagedConnection;
+import javax.resource.spi.ManagedConnectionFactory;
+import javax.resource.spi.RetryableException;
+import javax.resource.spi.ValidatingManagedConnectionFactory;
+import javax.security.auth.Subject;
+
+import org.jboss.logging.Messages;
+
+/**
+ * ManagedConnectionPool implementation based on a semaphore and ConcurrentLinkedDeque
+ * 
+ * @author John O'Hara 
+ * @author Jesper Pedersen 
+ */
+public class SemaphoreConcurrentLinkedDequeManagedConnectionPool implements ManagedConnectionPool 
+{
+   /** The log */
+   private CoreLogger log;
+
+   /** Whether debug is enabled */
+   private boolean debug;
+
+   /** The bundle */
+   private static CoreBundle bundle = Messages.getBundle(CoreBundle.class);
+
+   /** The managed connection factory */
+   private ManagedConnectionFactory mcf;
+
+   /** The connection manager */
+   private ConnectionManager cm;
+
+   /** The default subject */
+   private Subject defaultSubject;
+
+   /** The default connection request information */
+   private ConnectionRequestInfo defaultCri;
+
+   /** The pool configuration */
+   private PoolConfiguration poolConfiguration;
+
+   /** The pool */
+   private Pool pool;
+
+   /** FIFO / FILO */
+   private boolean fifo;
+   
+   /**
+    * Copy of the maximum size from the pooling parameters. Dynamic changes to
+    * this value are not compatible with the semaphore which cannot change be
+    * dynamically changed.
+    */
+   private int maxSize;
+
+   /** The available connection event listeners */
+   private ConcurrentLinkedDeque clq;
+
+   /** all connection event listeners */
+   private Map cls;
+
+   /** Current pool size **/
+   private AtomicInteger poolSize = new AtomicInteger();
+
+   /** Current checked out connections **/
+   private AtomicInteger checkedOutSize = new AtomicInteger();
+
+   /** Supports lazy association */
+   private Boolean supportsLazyAssociation;
+
+   /** Last idle check */
+   private long lastIdleCheck;
+
+   /** Last used */
+   private long lastUsed;
+
+   /**
+    * Constructor
+    */
+   public SemaphoreConcurrentLinkedDequeManagedConnectionPool() 
+   {
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void initialize(ManagedConnectionFactory mcf, ConnectionManager cm, Subject subject,
+                          ConnectionRequestInfo cri, PoolConfiguration pc, Pool p)
+   {
+      if (mcf == null)
+         throw new IllegalArgumentException("ManagedConnectionFactory is null");
+
+      if (cm == null)
+         throw new IllegalArgumentException("ConnectionManager is null");
+
+      if (pc == null)
+         throw new IllegalArgumentException("PoolConfiguration is null");
+
+      if (p == null)
+         throw new IllegalArgumentException("Pool is null");
+
+      this.mcf = mcf;
+      this.cm = cm;
+      this.defaultSubject = subject;
+      this.defaultCri = cri;
+      this.poolConfiguration = pc;
+      this.maxSize = pc.getMaxSize();
+      this.pool = p;
+      this.fifo = p.isFIFO();
+      this.log = pool.getLogger();
+      this.debug = log.isDebugEnabled();
+      this.clq = new ConcurrentLinkedDeque();
+      this.cls = new ConcurrentHashMap();
+      this.poolSize.set(0);
+      this.checkedOutSize.set(0);
+      this.supportsLazyAssociation = null;
+      this.lastIdleCheck = System.currentTimeMillis();
+      this.lastUsed = Long.MAX_VALUE;
+
+      // Schedule managed connection pool for prefill
+      if ((pc.isPrefill() || pc.isStrictMin()) && p instanceof PrefillPool && pc.getInitialSize() > 0) 
+      {
+         PoolFiller.fillPool(new FillRequest(this, pc.getInitialSize()));
+      }
+
+      if (poolConfiguration.getIdleTimeoutMinutes() > 0) 
+      {
+         // Register removal support
+         IdleRemover.getInstance().registerPool(this,
+                                                poolConfiguration.getIdleTimeoutMinutes() * 1000L * 60);
+      }
+
+      if (poolConfiguration.isBackgroundValidation() && poolConfiguration.getBackgroundValidationMillis() > 0) 
+      {
+         if (debug)
+            log.debug("Registering for background validation at interval " +
+                      poolConfiguration.getBackgroundValidationMillis());
+
+         // Register validation
+         ConnectionValidator.getInstance().registerPool(this,
+                                                        poolConfiguration.getBackgroundValidationMillis());
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public long getLastUsed() 
+   {
+      return lastUsed;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean isRunning() 
+   {
+      return !pool.isShutdown();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean isEmpty() 
+   {
+      return poolSize.get() == 0;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean isIdle() 
+   {
+      return checkedOutSize.get() == 0;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public int getActive() 
+   {
+      return poolSize.get();
+   }
+
+   /**
+    * Check if the pool has reached a certain size
+    * 
+    * @param size The size
+    * @return True if reached; otherwise false
+    */
+   private boolean isSize(int size) 
+   {
+      return poolSize.get() >= size;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void prefill() 
+   {
+      if (isRunning() &&
+          (poolConfiguration.isPrefill() || poolConfiguration.isStrictMin()) && 
+          pool instanceof PrefillPool && 
+          poolConfiguration.getMinSize() > 0)
+         PoolFiller.fillPool(new FillRequest(this, poolConfiguration.getMinSize()));
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public ConnectionListener getConnection(Subject subject, ConnectionRequestInfo cri) throws ResourceException 
+   {
+      if (log.isTraceEnabled()) 
+      {
+         synchronized (cls)
+         {
+            String method = "getConnection(" + subject + ", " + cri + ")";
+            SortedSet checkedOut = new TreeSet();
+            SortedSet available = new TreeSet();
+            for (Entry entry : cls.entrySet()) 
+            {
+               if (entry.getValue().isCheckedOut())
+                  checkedOut.add(entry.getKey());
+               else
+                  available.add(entry.getKey());
+            }
+            log.trace(ManagedConnectionPoolUtility.fullDetails(this, method, mcf, cm, pool,
+                                                               poolConfiguration, available, checkedOut,
+                                                               pool.getInternalStatistics(), subject, cri));
+         }
+      } 
+      else if (debug) 
+      {
+         String method = "getConnection(" + subject + ", " + cri + ")";
+         log.debug(ManagedConnectionPoolUtility.details(method, pool.getName(),
+                                                        pool.getInternalStatistics().getInUseCount(), maxSize));
+      }
+
+      subject = (subject == null) ? defaultSubject : subject;
+      cri = (cri == null) ? defaultCri : cri;
+
+      if (pool.isFull()) 
+      {
+         if (pool.getInternalStatistics().isEnabled())
+            pool.getInternalStatistics().deltaWaitCount();
+
+         if (pool.isSharable() && (supportsLazyAssociation == null || supportsLazyAssociation.booleanValue())) 
+         {
+            if (supportsLazyAssociation == null)
+               checkLazyAssociation();
+
+            if (supportsLazyAssociation != null && supportsLazyAssociation.booleanValue()) 
+            {
+               if (log.isTraceEnabled())
+                  log.tracef("Trying to detach - Pool: %s MCP: %s", pool.getName(), 
+                             Integer.toHexString(System.identityHashCode(this)));
+
+               if (!detachConnectionListener()) 
+               {
+                  if (log.isTraceEnabled())
+                     log.tracef("Detaching didn't succeed - Pool: %s MCP: %s", pool.getName(), 
+                                Integer.toHexString(System.identityHashCode(this)));
+               }
+            }
+         }
+      }
+
+      long startWait = pool.getInternalStatistics().isEnabled() ? System.currentTimeMillis() : 0L;
+      try 
+      {
+         if (pool.getLock().tryAcquire(poolConfiguration.getBlockingTimeout(), TimeUnit.MILLISECONDS)) 
+         {
+            if (pool.getInternalStatistics().isEnabled())
+               pool.getInternalStatistics().deltaTotalBlockingTime(System.currentTimeMillis() - startWait);
+
+            // We have a permit to get a connection. Is there one in the pool already?
+            ConnectionListenerWrapper clw = null;
+            do 
+            {
+               if (!isRunning()) 
+               {
+                  pool.getLock().release();
+
+                  throw new ResourceException(
+                     bundle.thePoolHasBeenShutdown(pool.getName(),
+                                                   Integer.toHexString(System.identityHashCode(this))));
+               }
+
+               if (fifo)
+               {
+                  clw = clq.pollFirst();
+               }
+               else
+               {
+                  clw = clq.pollLast();
+               }
+
+               if (clw != null) 
+               {
+                  clw.setCheckedOut(true);
+                  checkedOutSize.incrementAndGet();
+
+                  // Yes, we retrieved a ManagedConnection from the pool.
+                  // Does it match?
+                  try 
+                  {
+                     Object matchedMC = mcf.matchManagedConnections(Collections.singleton(
+                        clw.getConnectionListener().getManagedConnection()), subject, cri);
+
+                     boolean valid = true;
+
+                     if (matchedMC != null)
+                     {
+                        if (poolConfiguration.isValidateOnMatch())
+                        {
+                           if (mcf instanceof ValidatingManagedConnectionFactory)
+                           {
+                              try
+                              {
+                                 ValidatingManagedConnectionFactory vcf = (ValidatingManagedConnectionFactory) mcf;
+                                 Set candidateSet =
+                                    Collections.singleton(clw.getConnectionListener().getManagedConnection());
+                                 candidateSet = vcf.getInvalidConnections(candidateSet);
+
+                                 if (candidateSet != null && candidateSet.size() > 0)
+                                 {
+                                    valid = false;
+                                 }
+                              }
+                              catch (Throwable t)
+                              {
+                                 valid = false;
+                                 if (log.isTraceEnabled())
+                                    log.trace("Exception while ValidateOnMatch: " + t.getMessage(), t);
+                              }
+                           }
+                           else
+                           {
+                              log.validateOnMatchNonCompliantManagedConnectionFactory(mcf.getClass().getName());
+                           }
+                        }
+
+                        if (valid)
+                        {
+                           log.tracef("supplying ManagedConnection from pool: %s", clw.getConnectionListener());
+
+                           lastUsed = System.currentTimeMillis();
+                           clw.getConnectionListener().setLastCheckedOutTime(lastUsed);
+
+                           if (pool.getInternalStatistics().isEnabled())
+                           {
+                              pool.getInternalStatistics().deltaTotalGetTime(lastUsed - startWait);
+                              pool.getInternalStatistics().deltaTotalPoolTime(lastUsed -
+                                 clw.getConnectionListener().getLastReturnedTime());
+                           }
+
+                           if (Tracer.isEnabled())
+                              Tracer.getConnectionListener(pool.getName(), this, clw.getConnectionListener(),
+                                                           true, pool.isInterleaving(),
+                                                           Tracer.isRecordCallstacks() ?
+                                                           new Throwable("CALLSTACK") : null);
+
+                           clw.setHasPermit(true);
+
+                           return clw.getConnectionListener();
+                        }
+                     }
+
+                     // Match did not succeed but no exception was
+                     // thrown.
+                     // Either we have the matching strategy wrong or the
+                     // connection died while being checked. We need to
+                     // distinguish these cases, but for now we always
+                     // destroy the connection.
+                     if (valid)
+                     {
+                        log.destroyingConnectionNotSuccessfullyMatched(clw.getConnectionListener());
+                     }
+                     else
+                     {
+                        log.destroyingConnectionNotValidated(clw.getConnectionListener());
+                     }
+
+                     if (pool.getInternalStatistics().isEnabled())
+                     {
+                        pool.getInternalStatistics().deltaTotalPoolTime(System.currentTimeMillis() -
+                           clw.getConnectionListener().getLastReturnedTime());
+                     }
+
+                     if (Tracer.isEnabled())
+                        Tracer.destroyConnectionListener(pool.getName(), this, clw.getConnectionListener(),
+                                                         false, false, true, false, false, false, false,
+                                                         Tracer.isRecordCallstacks() ?
+                                                         new Throwable("CALLSTACK") : null);
+                     
+                     removeConnectionListenerFromPool(clw);
+                     clw.getConnectionListener().destroy();
+                     clw = null;
+                  } 
+                  catch (Throwable t) 
+                  {
+                     log.throwableWhileTryingMatchManagedConnectionThenDestroyingConnection(
+                        clw.getConnectionListener(), t);
+
+                     if (pool.getInternalStatistics().isEnabled())
+                     {
+                        pool.getInternalStatistics().deltaTotalPoolTime(System.currentTimeMillis() -
+                           clw.getConnectionListener().getLastReturnedTime());
+                     }
+
+                     if (Tracer.isEnabled())
+                        Tracer.destroyConnectionListener(pool.getName(), this, clw.getConnectionListener(),
+                                                         false, false, false, false, true, false, false,
+                                                         Tracer.isRecordCallstacks() ?
+                                                         new Throwable("CALLSTACK") : null);
+                     
+                     removeConnectionListenerFromPool(clw);
+                     clw.getConnectionListener().destroy();
+                     clw = null;
+                  }
+
+                  // We made it here, something went wrong and we should
+                  // validate
+                  // if we should continue attempting to acquire a
+                  // connection
+                  if (poolConfiguration.isUseFastFail()) 
+                  {
+                     if (log.isTraceEnabled())
+                        log.trace("Fast failing for connection attempt. No more attempts will be made to "
+                              + "acquire connection from pool and a new connection will be created immeadiately");
+                     break;
+                  }
+
+               } 
+            } 
+            while (clq.size() > 0);
+
+            // OK, we couldnt find a working connection from the pool. Make
+            // a new one.
+            try 
+            {
+               // No, the pool was empty, so we have to make a new one.
+               clw = new ConnectionListenerWrapper(createConnectionEventListener(subject, cri), true, true);
+
+               if (Tracer.isEnabled())
+                  Tracer.createConnectionListener(pool.getName(), this, clw.getConnectionListener(),
+                                                  clw.getConnectionListener().getManagedConnection(),
+                                                  true, false, false,
+                                                  Tracer.isRecordCallstacks() ?
+                                                  new Throwable("CALLSTACK") : null);
+
+               clw.setCheckedOut(true);
+               checkedOutSize.incrementAndGet();
+
+               cls.put(clw.getConnectionListener(), clw);
+
+               log.tracef("supplying new ManagedConnection: %s", clw.getConnectionListener());
+
+               lastUsed = System.currentTimeMillis();
+
+               if (pool.getInternalStatistics().isEnabled())
+                  pool.getInternalStatistics().deltaTotalGetTime(lastUsed - startWait);
+
+               prefill();
+
+               // Trigger capacity increase
+               if (pool.getCapacity().getIncrementer() != null)
+                  CapacityFiller.schedule(new CapacityRequest(this, subject, cri));
+
+               if (Tracer.isEnabled())
+                  Tracer.getConnectionListener(pool.getName(), this, clw.getConnectionListener(), false, 
+                                               pool.isInterleaving(),
+                                               Tracer.isRecordCallstacks() ?
+                                               new Throwable("CALLSTACK") : null);
+
+               return clw.getConnectionListener();
+            } 
+            catch (Throwable t) 
+            {
+               if (clw != null || !(t instanceof RetryableException))
+                  log.throwableWhileAttemptingGetNewGonnection(clw != null ? clw.getConnectionListener() : null, t);
+
+               // Return permit and rethrow
+               if (clw != null) 
+               {
+                  if (Tracer.isEnabled())
+                     Tracer.destroyConnectionListener(pool.getName(), this, clw.getConnectionListener(),
+                                                      false, false, false, false, true, false, false,
+                                                      Tracer.isRecordCallstacks() ?
+                                                      new Throwable("CALLSTACK") : null);
+                     
+                  removeConnectionListenerFromPool(clw);
+                  clw.getConnectionListener().destroy();
+               }
+
+               pool.getLock().release();
+
+               if (t instanceof ResourceException)
+               {
+                  throw (ResourceException)t;
+               }
+               else
+               {
+                  throw new ResourceException(
+                     bundle.unexpectedThrowableWhileTryingCreateConnection(
+                             clw != null ? clw.getConnectionListener() : null), t);
+               }
+            }
+         } 
+         else 
+         {
+            // We timed out
+            throw new ResourceException(
+               bundle.noMManagedConnectionsAvailableWithinConfiguredBlockingTimeout(
+                  poolConfiguration.getBlockingTimeout()));
+         }
+
+      } 
+      catch (InterruptedException ie) 
+      {
+         Thread.interrupted();
+
+         long end = pool.getInternalStatistics().isEnabled() ? (System.currentTimeMillis() - startWait) : 0L;
+         pool.getInternalStatistics().deltaTotalBlockingTime(end);
+         throw new ResourceException(bundle.interruptedWhileRequestingPermit(end));
+      } 
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public ConnectionListener findConnectionListener(ManagedConnection mc) 
+   {
+      return findConnectionListener(mc, null);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public ConnectionListener findConnectionListener(ManagedConnection mc, Object connection) 
+   {
+      for (Entry entry : cls.entrySet()) 
+      {
+         if (entry.getValue().isCheckedOut() && entry.getKey().controls(mc, connection))
+            return entry.getKey();
+      }
+      return null;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void returnConnection(ConnectionListener cl, boolean kill) 
+   {
+      returnConnection(cl, kill, true);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void returnConnection(ConnectionListener cl, boolean kill, boolean cleanup) 
+   {
+      if (pool.getInternalStatistics().isEnabled() && cl.getState() != ConnectionState.DESTROYED)
+         pool.getInternalStatistics().deltaTotalUsageTime(System.currentTimeMillis() - cl.getLastCheckedOutTime());
+
+      if (log.isTraceEnabled()) 
+      {
+         synchronized (cls)
+         {
+            String method = "returnConnection(" + Integer.toHexString(System.identityHashCode(cl)) + ", " + kill + ")";
+            SortedSet checkedOut = new TreeSet();
+            SortedSet available = new TreeSet();
+            for (Entry entry : cls.entrySet()) 
+            {
+               if (entry.getValue().isCheckedOut())
+                  checkedOut.add(entry.getKey());
+               else
+                  available.add(entry.getKey());
+            }
+            log.trace(ManagedConnectionPoolUtility.fullDetails(
+                  this, method, mcf, cm, pool,
+                  poolConfiguration, available, checkedOut, pool.getInternalStatistics(), defaultSubject, defaultCri));
+         }
+      } 
+      else if (debug) 
+      {
+         String method = "returnConnection(" + Integer.toHexString(System.identityHashCode(cl)) + ", " + kill + ")";
+         log.debug(ManagedConnectionPoolUtility.details(method,
+               pool.getName(), pool.getInternalStatistics().getInUseCount(), maxSize));
+      }
+
+      ConnectionListenerWrapper clw = cls.get(cl);
+      if (cl.getState() == ConnectionState.DESTROYED) 
+      {
+         log.tracef("ManagedConnection is being returned after it was destroyed: %s", cl);
+
+         if (clw != null && clw.hasPermit()) 
+         {
+            clw.setHasPermit(false);
+            pool.getLock().release();
+         }
+
+         return;
+      }
+
+      if (cleanup) 
+      {
+         try 
+         {
+            cl.getManagedConnection().cleanup();
+         }
+         catch (ResourceException re) 
+         {
+            log.resourceExceptionCleaningUpManagedConnection(cl, re);
+            kill = true;
+         }
+      }
+
+      // We need to destroy this one
+      if (clw == null || cl.getState() == ConnectionState.DESTROY || cl.getState() == ConnectionState.DESTROYED)
+         kill = true;
+
+      // This is really an error
+      if (!kill && isSize(poolConfiguration.getMaxSize() + 1))
+      {
+         log.destroyingReturnedConnectionMaximumPoolSizeExceeded(cl);
+         kill = true;
+      }
+
+      boolean releasePermit = false;
+      if (clw != null)
+      {
+         if (clw.hasPermit())
+         {
+            clw.setHasPermit(false);
+            releasePermit = true;
+         }
+         if (clw.isCheckedOut())
+         {
+            clw.setCheckedOut(false);
+            checkedOutSize.decrementAndGet();
+         }
+      }
+
+      // If we are destroying, check the connection is not in the pool
+      if (kill) 
+      {
+         // Adrian Brock: A resource adapter can asynchronously notify us
+         // that a connection error occurred.
+         // This could happen while the connection is not checked out.
+         // e.g. JMS can do this via an ExceptionListener on the connection.
+         // I have twice had to reinstate this line of code, PLEASE DO NOT
+         // REMOVE IT!
+         cls.remove(cl);
+      }
+      // return to the pool
+      else 
+      {
+         cl.toPool();
+         if (!clq.contains(clw)) 
+         {
+            clq.addLast(clw);
+         } 
+         else 
+         {
+            log.attemptReturnConnectionTwice(cl, new Throwable("STACKTRACE"));
+         }
+      }
+
+      if (kill)
+      {
+         log.tracef("Destroying returned connection %s", cl);
+
+         if (Tracer.isEnabled())
+            Tracer.destroyConnectionListener(pool.getName(), this, cl,
+                                             true, false, false, false, false, false, false,
+                                             Tracer.isRecordCallstacks() ?
+                                             new Throwable("CALLSTACK") : null);
+                     
+         removeConnectionListenerFromPool(clw);
+         cl.destroy();
+      }
+
+      if (releasePermit)
+      {
+         pool.getLock().release();
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void flush(FlushMode mode, Collection toDestroy)
+   {
+      ArrayList destroy = null;
+
+      synchronized (cls)
+      {
+         if (FlushMode.ALL == mode) 
+         {
+            if (log.isTraceEnabled()) 
+            {
+               SortedSet checkedOut = new TreeSet();
+               for (Entry entry : cls.entrySet()) 
+               {
+                  if (entry.getValue().isCheckedOut())
+                     checkedOut.add(entry.getKey());
+               }
+               log.tracef("Flushing pool checkedOut=%s inPool=%s", checkedOut , cls);
+            }
+
+            // Mark checked out connections as requiring destruction
+            for (Entry entry : cls.entrySet()) 
+            {
+               if (entry.getValue().isCheckedOut()) 
+               {
+                  log.tracef("Flush marking checked out connection for destruction %s", entry.getKey());
+
+                  entry.getValue().setCheckedOut(false);
+                  checkedOutSize.decrementAndGet();
+
+                  if (pool.getInternalStatistics().isEnabled())
+                     pool.getInternalStatistics().deltaTotalUsageTime(System.currentTimeMillis() -
+                                                                      entry.getKey().getLastCheckedOutTime());
+
+                  if (entry.getValue().hasPermit())
+                  {
+                     entry.getValue().setHasPermit(false);
+                     pool.getLock().release();
+                  }
+
+                  entry.getKey().setState(ConnectionState.DESTROY);
+
+                  if (destroy == null)
+                     destroy = new ArrayList(1);
+
+                  destroy.add(entry.getValue());
+
+                  clq.remove(entry.getValue());
+                  cls.remove(entry.getKey());
+               }
+            }
+         } 
+         else if (FlushMode.GRACEFULLY == mode) 
+         {
+            if (log.isTraceEnabled()) 
+            {
+               SortedSet checkedOut = new TreeSet();
+               for (Entry entry : cls.entrySet()) 
+               {
+                  if (entry.getValue().isCheckedOut())
+                     checkedOut.add(entry.getKey());
+               }
+               log.tracef("Gracefully flushing pool checkedOut=%s inPool=%s", checkedOut , cls);
+            }
+
+            for (Entry entry : cls.entrySet()) 
+            {
+               if (entry.getValue().isCheckedOut()) 
+               {
+                  log.tracef("Graceful flush marking checked out connection for destruction %s", entry.getKey());
+                  
+                  entry.getKey().setState(ConnectionState.DESTROY);
+               }
+            }
+
+         }
+
+         // Destroy connections in the pool
+         Iterator clqIter = clq.iterator();
+         while (clqIter.hasNext()) 
+         {
+            ConnectionListenerWrapper clw = clqIter.next();
+            boolean kill = true;
+
+            if (FlushMode.INVALID == mode && clw.getConnectionListener().getState().equals(ConnectionState.NORMAL)) 
+            {
+               if (mcf instanceof ValidatingManagedConnectionFactory) 
+               {
+                  try 
+                  {
+                     ValidatingManagedConnectionFactory vcf = (ValidatingManagedConnectionFactory) mcf;
+                     Set candidateSet = Collections.singleton(clw.getConnectionListener().getManagedConnection());
+                     candidateSet = vcf.getInvalidConnections(candidateSet);
+
+                     if (candidateSet == null || candidateSet.size() == 0) 
+                     {
+                        kill = false;
+                     }
+                  } 
+                  catch (Throwable t) 
+                  {
+                     log.trace("Exception during invalid flush", t);
+                  }
+               }
+            }
+
+            if (kill) 
+            {
+               if (pool.getInternalStatistics().isEnabled())
+                  pool.getInternalStatistics().deltaTotalPoolTime(System.currentTimeMillis() -
+                                                                  clw.getConnectionListener().getLastReturnedTime());
+
+               clq.remove(clw);
+               cls.remove(clw.getConnectionListener());
+
+               if (destroy == null)
+                  destroy = new ArrayList(1);
+
+               clw.getConnectionListener().setState(ConnectionState.DESTROY);
+               destroy.add(clw);
+            }
+
+         }
+      }
+
+      // We need to destroy some connections
+      if (destroy != null) 
+      {
+         for (ConnectionListenerWrapper clw : destroy)
+         {
+            removeConnectionListenerFromPool(clw);
+            toDestroy.add(clw.getConnectionListener());
+            clw = null;
+         }
+      }
+
+      // Trigger prefill
+      prefill();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void removeIdleConnections() 
+   {
+      long now = System.currentTimeMillis();
+      long timeoutSetting = poolConfiguration.getIdleTimeoutMinutes() * 1000L * 60;
+
+      CapacityDecrementer decrementer = pool.getCapacity().getDecrementer();
+
+      if (decrementer == null)
+         decrementer = DefaultCapacity.DEFAULT_DECREMENTER;
+
+      if (TimedOutDecrementer.class.getName().equals(decrementer.getClass().getName()) ||
+          TimedOutFIFODecrementer.class.getName().equals(decrementer.getClass().getName()))
+      {
+         // Allow through each minute
+         if (now < (lastIdleCheck + 60000L))
+            return;
+      }
+      else
+      {
+         // Otherwise, strict check
+         if (now < (lastIdleCheck + timeoutSetting))
+            return;
+      }
+
+      lastIdleCheck = now;
+
+      ArrayList destroyConnections = new ArrayList();
+      long timeout = now - timeoutSetting;
+
+      boolean destroy = true;
+      int destroyed = 0;
+
+      if (log.isTraceEnabled()) 
+      {
+         synchronized (cls) 
+         {
+            String method = "removeIdleConnections(" + timeout + ")";
+            SortedSet checkedOut = new TreeSet();
+            SortedSet available = new TreeSet();
+            for (Entry entry : cls.entrySet()) 
+            {
+               if (entry.getValue().isCheckedOut())
+                  checkedOut.add(entry.getKey());
+               else
+                  available.add(entry.getKey());
+            }
+            log.trace(ManagedConnectionPoolUtility.fullDetails(
+                  this, method, mcf, cm, pool,
+                  poolConfiguration, available, checkedOut, pool.getInternalStatistics(), defaultSubject, defaultCri));
+         }
+      } 
+      else if (debug) 
+      {
+         String method = "removeIdleConnections(" + timeout + ")";
+         log.debug(ManagedConnectionPoolUtility.details(method, pool.getName(),
+                                                        pool.getInternalStatistics().getInUseCount(), maxSize));
+      }
+
+      Iterator clwIter = clq.iterator();
+      while (clwIter.hasNext() && destroy) 
+      {
+         // Nothing left to destroy
+         if (clq.size() == 0)
+            break;
+
+         ConnectionListenerWrapper clw = clwIter.next();
+
+         destroy = decrementer.shouldDestroy(clw.getConnectionListener(),
+                                             timeout, poolSize.get() - destroyed,
+                                             poolConfiguration.getMinSize(), destroyed);
+
+         if (destroy) 
+         {
+            if (shouldRemove() || !isRunning())
+            {
+               if (pool.getInternalStatistics().isEnabled())
+                  pool.getInternalStatistics().deltaTimedOut();
+
+               log.tracef("Idle connection cl=%s", clw.getConnectionListener());
+
+               // We need to destroy this one, so deregister now
+               if (cls.remove(clw.getConnectionListener()) == null) 
+                  log.tracef("Connection Pool did not contain: %s", clw.getConnectionListener());
+
+               if (!clq.remove(clw)) 
+                  log.tracef("Available connection queue did not contain: %s", clw.getConnectionListener());
+
+               destroyConnections.add(clw);
+               destroyed++;
+            } 
+            else 
+            {
+               destroy = false;
+            }
+         }
+      }
+
+      // We found some connections to destroy
+      if (destroyConnections.size() > 0 || isEmpty())
+      {
+         for (ConnectionListenerWrapper clw : destroyConnections) 
+         {
+            log.tracef("Destroying connection %s", clw.getConnectionListener());
+
+            if (pool.getInternalStatistics().isEnabled())
+               pool.getInternalStatistics().deltaTotalPoolTime(System.currentTimeMillis() -
+                                                               clw.getConnectionListener().getLastReturnedTime());
+
+            if (Tracer.isEnabled())
+               Tracer.destroyConnectionListener(pool.getName(), this, clw.getConnectionListener(),
+                                                false, true, false, false, false, false, false,
+                                                Tracer.isRecordCallstacks() ?
+                                                new Throwable("CALLSTACK") : null);
+                     
+            removeConnectionListenerFromPool(clw);
+            clw.getConnectionListener().destroy();
+            clw = null;
+         }
+
+         if (isRunning()) 
+         {
+            // Let prefill and use-strict-min be the same
+            boolean emptyManagedConnectionPool = false;
+
+            if ((poolConfiguration.isPrefill() || poolConfiguration.isStrictMin()) && pool instanceof PrefillPool) 
+            {
+               if (poolConfiguration.getMinSize() > 0) 
+               {
+                  prefill();
+               }
+               else 
+               {
+                  emptyManagedConnectionPool = true;
+               }
+            } 
+            else 
+            {
+               emptyManagedConnectionPool = true;
+            }
+
+            // Empty pool
+            if (emptyManagedConnectionPool && isEmpty())
+               pool.emptyManagedConnectionPool(this);
+         }
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void shutdown()
+   {
+      if (log.isTraceEnabled())
+         log.tracef("Shutdown - Pool: %s MCP: %s", pool.getName(), Integer.toHexString(System.identityHashCode(this)));
+
+      IdleRemover.getInstance().unregisterPool(this);
+      ConnectionValidator.getInstance().unregisterPool(this);
+
+      if (checkedOutSize.get() > 0)
+      {
+         for (Entry entry : cls.entrySet())
+         {
+            if (entry.getValue().isCheckedOut())
+               log.destroyingActiveConnection(pool.getName(), entry.getKey().getManagedConnection());
+
+            if (Tracer.isEnabled())
+               Tracer.clearConnectionListener(pool.getName(), this, entry.getKey());
+
+         }
+      }
+
+      final Collection toDestroy = new ArrayList();
+      flush(FlushMode.ALL, toDestroy);
+      for (ConnectionListener cl : toDestroy)
+      {
+         cl.destroy();
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void fillTo(int size) 
+   {
+      if (size <= 0)
+         return;
+
+      if (!(poolConfiguration.isPrefill() || poolConfiguration.isStrictMin()))
+         return;
+
+      if (!(pool instanceof PrefillPool))
+         return;
+
+      if (log.isTraceEnabled()) 
+      {
+         synchronized (cls) 
+         {
+            String method = "fillTo(" + size + ")";
+            SortedSet checkedOut = new TreeSet();
+            SortedSet available = new TreeSet();
+            for (Entry entry : cls.entrySet()) 
+            {
+               if (entry.getValue().isCheckedOut())
+                  checkedOut.add(entry.getKey());
+               else
+                  available.add(entry.getKey());
+            }
+            log.trace(ManagedConnectionPoolUtility.fullDetails(
+                  this, method, mcf, cm, pool,
+                  poolConfiguration, available, checkedOut, pool.getInternalStatistics(), defaultSubject, defaultCri));
+         }
+      } 
+      else if (debug) 
+      {
+         String method = "fillTo(" + size + ")";
+         log.debug(ManagedConnectionPoolUtility.details(method, pool.getName(),
+                                                        pool.getInternalStatistics().getInUseCount(), maxSize));
+      }
+
+      while (!pool.isFull())
+      {
+         // Get a permit - avoids a race when the pool is nearly full
+         // Also avoids unnessary fill checking when all connections are
+         // checked out
+         try 
+         {
+            long startWait = pool.getInternalStatistics().isEnabled() ? System.currentTimeMillis() : 0L;
+            if (pool.getLock().tryAcquire(poolConfiguration.getBlockingTimeout(), TimeUnit.MILLISECONDS)) 
+            {
+               if (pool.getInternalStatistics().isEnabled())
+                  pool.getInternalStatistics().deltaTotalBlockingTime(System.currentTimeMillis() - startWait);
+               try 
+               {
+                  if (!isRunning()) 
+                  {
+                     return;
+                  }
+
+                  // We already have enough connections
+                  if (isSize(size)) 
+                  {
+                     return;
+                  }
+
+                  // Create a connection to fill the pool
+                  try 
+                  {
+                     ConnectionListener cl = createConnectionEventListener(defaultSubject, defaultCri);
+
+                     if (Tracer.isEnabled())
+                        Tracer.createConnectionListener(pool.getName(), this, cl, cl.getManagedConnection(),
+                                                        false, true, false,
+                                                        Tracer.isRecordCallstacks() ?
+                                                        new Throwable("CALLSTACK") : null);
+
+                     boolean added = false;
+                     // We have to add 1, since poolSize is already incremented
+                     if (!isSize(size + 1))
+                     {
+                        log.tracef("Filling pool cl=%s", cl);
+
+                        cls.put(cl, new ConnectionListenerWrapper(cl, false, false));
+                        clq.addLast(cls.get(cl));
+                        added = true;
+                     }
+
+                     if (!added)
+                     {
+                        if (Tracer.isEnabled())
+                           Tracer.destroyConnectionListener(pool.getName(), this, cl, false, false, false, false,
+                                                            false, true, false,
+                                                            Tracer.isRecordCallstacks() ?
+                                                            new Throwable("CALLSTACK") : null);
+                     
+                        ConnectionListenerWrapper clw = new ConnectionListenerWrapper(cl, false, false);
+                        removeConnectionListenerFromPool(clw);
+                        clw.getConnectionListener().destroy();
+                        return;
+                     }
+                  }
+                  catch (ResourceException re) 
+                  {
+                     log.unableFillPool(re, cm.getJndiName());
+                     return;
+                  }
+               } 
+               finally 
+               {
+                  pool.getLock().release();
+               }
+            }
+         } 
+         catch (InterruptedException ignored) 
+         {
+            Thread.interrupted();
+
+            log.trace("Interrupted while requesting permit in fillTo");
+         }
+      }
+   }
+
+   @Override
+   public void increaseCapacity(Subject subject, ConnectionRequestInfo cri) 
+   {
+      // We have already created one connection when this method is scheduled
+      int created = 1;
+      boolean create = true;
+
+      while (create && !pool.isFull()) 
+      {
+         try 
+         {
+            long startWait = pool.getInternalStatistics().isEnabled() ? System.currentTimeMillis() : 0L;
+            if (pool.getLock().tryAcquire(poolConfiguration.getBlockingTimeout(), TimeUnit.MILLISECONDS)) 
+            {
+               if (pool.getInternalStatistics().isEnabled())
+                  pool.getInternalStatistics().deltaTotalBlockingTime(System.currentTimeMillis() - startWait);
+               try 
+               {
+                  if (!isRunning()) 
+                  {
+                     return;
+                  }
+
+                  create = pool.getCapacity().getIncrementer().shouldCreate(poolSize.get(),
+                                                                            poolConfiguration.getMaxSize(), created);
+
+                  if (create) 
+                  {
+                     try 
+                     {
+                        ConnectionListener cl = createConnectionEventListener(subject, cri);
+
+                        if (Tracer.isEnabled())
+                           Tracer.createConnectionListener(pool.getName(), this, cl, cl.getManagedConnection(),
+                                                           false, false, true,
+                                                           Tracer.isRecordCallstacks() ?
+                                                           new Throwable("CALLSTACK") : null);
+
+                        boolean added = false;
+                        // We have to add 1, since poolSize is already incremented
+                        if (!isSize(poolConfiguration.getMaxSize() + 1))
+                        {
+                           log.tracef("Capacity fill: cl=%s", cl);
+
+                           cls.put(cl, new ConnectionListenerWrapper(cl, false, false));
+                           clq.addLast(cls.get(cl));
+
+                           created++;
+                           added = true;
+                        }
+
+                        if (!added)
+                        {
+                           if (Tracer.isEnabled())
+                              Tracer.destroyConnectionListener(pool.getName(), this, cl, false, false, true, false,
+                                                               false, false, true,
+                                                               Tracer.isRecordCallstacks() ?
+                                                               new Throwable("CALLSTACK") : null);
+                     
+                           ConnectionListenerWrapper clw = new ConnectionListenerWrapper(cl, false, false);
+                           removeConnectionListenerFromPool(clw);
+                           clw.getConnectionListener().destroy();
+                           return;
+                        }
+                     } 
+                     catch (ResourceException re) 
+                     {
+                        log.unableFillPool(re, cm.getJndiName());
+                        return;
+                     }
+                  }
+               } 
+               finally 
+               {
+                  pool.getLock().release();
+               }
+            }
+         } 
+         catch (InterruptedException ignored) 
+         {
+            Thread.interrupted();
+
+            log.trace("Interrupted while requesting permit in increaseCapacity");
+         }
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void addConnectionListener(ConnectionListener cl) 
+   {
+      cls.put(cl, new ConnectionListenerWrapper(cl, false, false));
+      clq.addLast(cls.get(cl));
+      poolSize.incrementAndGet();
+
+      if (pool.getInternalStatistics().isEnabled())
+         pool.getInternalStatistics().deltaCreatedCount();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public ConnectionListener removeConnectionListener() 
+   {
+      if (cls.size() > 0) 
+      {
+         if (pool.getInternalStatistics().isEnabled())
+            pool.getInternalStatistics().deltaDestroyedCount();
+         ConnectionListenerWrapper clw = clq.removeFirst();
+         if (cls.remove(clw.getConnectionListener()) != null)
+            poolSize.decrementAndGet();
+         return clw.getConnectionListener();
+      }
+
+      return null;
+   }
+
+   /**
+    * Create a connection event listener
+    * 
+    * @param subject
+    *            the subject
+    * @param cri
+    *            the connection request information
+    * @return the new listener
+    * @throws ResourceException
+    *             for any error
+    */
+   private ConnectionListener createConnectionEventListener(Subject subject, ConnectionRequestInfo cri) 
+      throws ResourceException 
+   {
+      long start = pool.getInternalStatistics().isEnabled() ? System.currentTimeMillis() : 0L;
+
+      ManagedConnection mc = mcf.createManagedConnection(subject, cri);
+
+      if (pool.getInternalStatistics().isEnabled()) 
+      {
+         pool.getInternalStatistics().deltaTotalCreationTime(System.currentTimeMillis() - start);
+         pool.getInternalStatistics().deltaCreatedCount();
+      }
+      try 
+      {
+         ConnectionListener cl = cm.createConnectionListener(mc, this);
+         poolSize.incrementAndGet();
+         return cl;
+      } 
+      catch (ResourceException re) 
+      {
+         if (pool.getInternalStatistics().isEnabled())
+            pool.getInternalStatistics().deltaDestroyedCount();
+         mc.destroy();
+         throw re;
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void connectionListenerDestroyed(ConnectionListener cl)
+   {
+      if (pool.getInternalStatistics().isEnabled())
+         pool.getInternalStatistics().deltaDestroyedCount();
+   }
+
+   /**
+    * Remove Connection Listener from pool and update counters and statistics
+    *
+    * Note, that the ConnectionListenerWrapper may already have been removed
+    * @param clw The wrapper
+    */
+   private void removeConnectionListenerFromPool(ConnectionListenerWrapper clw)
+   {
+      if (clw != null)
+      {
+         clq.remove(clw);
+         cls.remove(clw.getConnectionListener());
+
+         //update counter and statistics
+         if (clw.isCheckedOut()) 
+         {
+            clw.setCheckedOut(false);
+            checkedOutSize.decrementAndGet();
+         }
+         // update pool size
+         poolSize.decrementAndGet();
+      }
+   }
+   
+   /**
+    * Should any connections be removed from the pool
+    * 
+    * @return True if connections should be removed; otherwise false
+    */
+   private boolean shouldRemove() 
+   {
+      boolean remove = true;
+
+      if (poolConfiguration.isStrictMin() && pool instanceof PrefillPool) 
+      {
+         // Add 1 to min-pool-size since it is strict
+         remove = isSize(poolConfiguration.getMinSize() + 1);
+
+         log.tracef("StrictMin is active. Current connection will be removed is %b", remove);
+      }
+
+      return remove;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public void validateConnections() throws Exception 
+   {
+
+      log.tracef("Attempting to validate connections for pool %s", this);
+
+      if (pool.getLock().tryAcquire(poolConfiguration.getBlockingTimeout(), TimeUnit.MILLISECONDS)) 
+      {
+         boolean anyDestroyed = false;
+
+         try 
+         {
+            while (true) 
+            {
+               ConnectionListener cl = null;
+               boolean destroyed = false;
+
+               synchronized (cls)
+               {
+                  if (clq.size() == 0) 
+                  {
+                     break;
+                  }
+
+                  cl = removeForFrequencyCheck();
+               }
+
+               if (cl == null) 
+               {
+                  break;
+               }
+
+               try 
+               {
+                  Set candidateSet = Collections.singleton(cl.getManagedConnection());
+
+                  if (mcf instanceof ValidatingManagedConnectionFactory) 
+                  {
+                     ValidatingManagedConnectionFactory vcf = (ValidatingManagedConnectionFactory) mcf;
+                     candidateSet = vcf.getInvalidConnections(candidateSet);
+
+                     if ((candidateSet != null && candidateSet.size() > 0) || !isRunning())
+                     {
+                        if (cl.getState() != ConnectionState.DESTROY) 
+                        {
+                           ConnectionListenerWrapper clw = cls.remove(cl);
+
+                           if (pool.getInternalStatistics().isEnabled())
+                              pool.getInternalStatistics().deltaTotalPoolTime(System.currentTimeMillis() -
+                                 clw.getConnectionListener().getLastReturnedTime());
+
+                           if (Tracer.isEnabled())
+                              Tracer.destroyConnectionListener(pool.getName(), this, clw.getConnectionListener(),
+                                                               false, false, true, false, false, false, false,
+                                                               Tracer.isRecordCallstacks() ?
+                                                               new Throwable("CALLSTACK") : null);
+                     
+                           removeConnectionListenerFromPool(clw);
+                           clw.getConnectionListener().destroy();
+                           clw = null;
+                           destroyed = true;
+                           anyDestroyed = true;
+                        }
+                     }
+                  } 
+                  else 
+                  {
+                     log.backgroundValidationNonCompliantManagedConnectionFactory();
+                  }
+               } 
+               catch (ResourceException re) 
+               {
+                  if (cl != null) 
+                  {
+                     ConnectionListenerWrapper clw = cls.remove(cl);
+
+                     if (pool.getInternalStatistics().isEnabled())
+                        pool.getInternalStatistics().deltaTotalPoolTime(System.currentTimeMillis() -
+                           clw.getConnectionListener().getLastReturnedTime());
+
+                     if (Tracer.isEnabled())
+                        Tracer.destroyConnectionListener(pool.getName(), this, clw.getConnectionListener(),
+                                                         false, false, false, false, true, false, false,
+                                                         Tracer.isRecordCallstacks() ?
+                                                         new Throwable("CALLSTACK") : null);
+                     
+                     removeConnectionListenerFromPool(clw);
+                     clw.getConnectionListener().destroy();
+                     clw = null;
+                     destroyed = true;
+                     anyDestroyed = true;
+                  }
+
+                  log.connectionValidatorIgnoredUnexpectedError(re);
+               } 
+               finally 
+               {
+                  if (!destroyed) 
+                  {
+                     synchronized (cls)
+                     {
+                        returnForFrequencyCheck(cl);
+                     }
+                  }
+               }
+            }
+         } 
+         finally 
+         {
+            pool.getLock().release();
+
+            if (anyDestroyed)
+                prefill();
+         }
+      }
+   }
+
+   /**
+    * Get the pool name
+    * @return The value
+    */
+   String getPoolName()
+   {
+      if (pool == null)
+         return "";
+
+      return pool.getName();
+   }
+
+   /**
+    * Returns the connection listener that should be removed due to background
+    * validation
+    * 
+    * @return The listener; otherwise null if none should be removed
+    */
+   private ConnectionListener removeForFrequencyCheck() 
+   {
+      log.debug("Checking for connection within frequency");
+
+      ConnectionListenerWrapper clw = null;
+
+      for (Iterator iter = clq.iterator(); iter.hasNext();) 
+      {
+         clw = iter.next();
+         long lastCheck = clw.getConnectionListener().getLastValidatedTime();
+
+         if ((System.currentTimeMillis() - lastCheck) >= poolConfiguration.getBackgroundValidationMillis()) 
+         {
+            clq.remove(clw);
+            break;
+         } 
+         else 
+         {
+            clw = null;
+         }
+      }
+
+      if (clw != null)
+         return clw.getConnectionListener();
+      else
+         return null;
+   }
+
+   /**
+    * Return a connection listener to the pool and update its validation
+    * timestamp
+    * 
+    * @param cl
+    *            The listener
+    */
+   private void returnForFrequencyCheck(ConnectionListener cl) 
+   {
+      log.debug("Returning for connection within frequency");
+
+      cl.setLastValidatedTime(System.currentTimeMillis());
+      clq.addLast(cls.get(cl));
+   }
+
+   /**
+    * Check if the resource adapter supports lazy association
+    */
+   private void checkLazyAssociation() 
+   {
+      ConnectionListener cl = null;
+
+      if (cls.size() > 0)
+         cl = cls.keySet().iterator().next();
+
+      if (cl != null) 
+      {
+         if (cl.supportsLazyAssociation()) 
+         {
+            if (debug)
+               log.debug("Enable lazy association support for: " + pool.getName());
+
+            supportsLazyAssociation = Boolean.TRUE;
+         } 
+         else 
+         {
+            if (debug)
+               log.debug("Disable lazy association support for: " + pool.getName());
+
+            supportsLazyAssociation = Boolean.FALSE;
+         }
+      }
+   }
+
+   /**
+    * Detach connection listener
+    * 
+    * @return The outcome
+    */
+   private boolean detachConnectionListener() 
+   {
+      synchronized (cls) 
+      {
+         ConnectionListener cl = null;
+         try 
+         {
+            for (Entry entry : cls.entrySet()) 
+            {
+               cl = entry.getKey();
+               
+               if (entry.getValue().isCheckedOut()) 
+               {
+                  if (!cl.isEnlisted() && cl.getManagedConnection() instanceof DissociatableManagedConnection) 
+                  {
+                     log.tracef("Detach: %s", cl);
+
+                     DissociatableManagedConnection dmc = (DissociatableManagedConnection) cl.getManagedConnection();
+                     dmc.dissociateConnections();
+
+                     cl.unregisterConnections();
+
+                     if (Tracer.isEnabled())
+                        Tracer.returnConnectionListener(pool.getName(), this, cl, false, pool.isInterleaving(),
+                                                        Tracer.isRecordCallstacks() ?
+                                                        new Throwable("CALLSTACK") : null);
+
+                     returnConnection(cl, false, false);
+
+                     return true;
+                  }
+               }
+            }
+         } 
+         catch (Throwable t) 
+         {
+            // Ok - didn't work; nuke it and disable
+            if (debug)
+               log.debug("Exception during detach for: " + pool.getName(),
+                     t);
+
+            supportsLazyAssociation = Boolean.FALSE;
+
+            if (cl != null) 
+            {
+               if (Tracer.isEnabled())
+                  Tracer.returnConnectionListener(pool.getName(), this, cl, true, pool.isInterleaving(),
+                                                  Tracer.isRecordCallstacks() ?
+                                                  new Throwable("CALLSTACK") : null);
+
+               returnConnection(cl, true, true);
+            }
+         }
+      }
+
+      return false;
+   }
+
+   /**
+    * String representation
+    * 
+    * @return The string
+    */
+   @Override
+   public String toString() 
+   {
+      StringBuilder sb = new StringBuilder();
+
+      sb.append("SemaphoreConcurrentLinkedQueueManagedConnectionPool@");
+      sb.append(Integer.toHexString(System.identityHashCode(this)));
+      sb.append("[pool=").append(pool.getName());
+      sb.append("]");
+
+      return sb.toString();
+   }
+
+   /**
+    * Connection Listener wrapper to retain connection listener pool state
+    * 
+    * @author John O'Hara 
+    * @author Jesper Pedersen 
+    */
+   static class ConnectionListenerWrapper 
+   {
+      private volatile ConnectionListener cl;
+      private volatile boolean checkedOut;
+      private volatile boolean hasPermit;
+
+      /**
+       * Constructor
+       * 
+       * @param connectionListener wrapped Connection Listener
+       */
+      public ConnectionListenerWrapper(ConnectionListener connectionListener) 
+      {
+         this(connectionListener, false, false);
+      }
+
+      /**
+       * Constructor
+       * 
+       * @param connectionListener wrapped Connection Listener
+       * @param checkedOut is connection listener checked out
+       */
+      public ConnectionListenerWrapper(ConnectionListener connectionListener, boolean checkedOut) 
+      {
+         this(connectionListener, checkedOut, false);
+      }
+
+      /**
+       * Constructor
+       * 
+       * @param connectionListener wrapped Connection Listener
+       * @param checkedOut is connection listener checked out
+       * @param hasPermit does connection listener have a permit
+       */
+      public ConnectionListenerWrapper(ConnectionListener connectionListener, boolean checkedOut, boolean hasPermit) 
+      {
+         this.cl = connectionListener;
+         this.checkedOut = checkedOut;
+         this.hasPermit = hasPermit;
+      }
+
+      /**
+       * Get wrapped Connection Listener
+       * 
+       * @return Wrapped Connection Listener
+       */
+      public ConnectionListener getConnectionListener() 
+      {
+         return cl;
+      }
+
+      /**
+       * Is Connection Listener checked out
+       * 
+       * @return Connection Listener is checked out
+       */
+      public boolean isCheckedOut() 
+      {
+         return checkedOut;
+      }
+
+      /**
+       * Set whether Connection Listener is checkout out
+       * 
+       * @param checkedOut is connection listener checked out
+       */
+      public void setCheckedOut(boolean checkedOut)
+      {
+         this.checkedOut = checkedOut;
+      }
+
+      /**
+       * Does Connection Listener have a permit
+       * 
+       * @return Connection Listener has a permit
+       */
+      public boolean hasPermit() 
+      {
+         return hasPermit;
+      }
+
+      /**
+       * Set whether Connection Listener has permit
+       * 
+       * @param hasPermit does connection listener have a permit
+       */
+      public void setHasPermit(boolean hasPermit) 
+      {
+         this.hasPermit = hasPermit;
+      }
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/package.html
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/package.html	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/mcp/package.html	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,4 @@
+
+This package contains the managed connection pool implementations and the
+factory to create one with.
+
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/package.html
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/package.html	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/package.html	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,3 @@
+
+This package contains the connection pool implementation.
+
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/CriKey.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/CriKey.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/CriKey.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,86 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2008-2009, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager.pool.strategy;
+
+import javax.resource.spi.ConnectionRequestInfo;
+
+/**
+ * Pool by {@link ConnectionRequestInfo} key.
+ * 
+ * @author Gurkan Erdogdu 
+ * @version $Rev: $
+ */
+class CriKey
+{
+   /** Identifies no connection request information */
+   private static final Object NOCRI = new Object();
+   
+   /** The connection request information */
+   private final Object cri;
+
+   /** Separate no tx */
+   private boolean separateNoTx;
+   
+   /** The cached hashCode */
+   private int hashCode = Integer.MAX_VALUE;
+
+   /**
+    * Creates a new instance.
+    * @param cri connection request info
+    * @param separateNoTx separateNoTx
+    */
+   CriKey(ConnectionRequestInfo cri, boolean separateNoTx) 
+   {
+      this.cri = (cri == null) ? NOCRI : cri;
+      this.separateNoTx = separateNoTx;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public int hashCode()
+   {
+      if (hashCode == Integer.MAX_VALUE)
+         hashCode = cri.hashCode();
+
+      return hashCode;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public boolean equals(Object obj)
+   {
+      if (this == obj)
+         return true;  
+
+      if (obj == null || !(obj instanceof CriKey))
+         return false;  
+      
+      CriKey other = (CriKey) obj;
+
+      return cri.equals(other.cri) && separateNoTx == other.separateNoTx;
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/OnePool.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/OnePool.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/OnePool.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,111 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2011, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager.pool.strategy;
+
+import org.jboss.jca.core.CoreLogger;
+import org.jboss.jca.core.api.connectionmanager.pool.PoolConfiguration;
+import org.jboss.jca.core.connectionmanager.pool.AbstractPrefillPool;
+import org.jboss.jca.core.connectionmanager.pool.mcp.ManagedConnectionPool;
+
+import javax.resource.spi.ConnectionRequestInfo;
+import javax.resource.spi.ManagedConnectionFactory;
+import javax.security.auth.Subject;
+
+import org.jboss.logging.Logger;
+
+/**
+ * Single pool implementation.
+ * 
+ * @author Gurkan Erdogdu 
+ * @author Jesper Pedersen 
+ */
+public class OnePool extends AbstractPrefillPool
+{
+   /** The logger */
+   private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, OnePool.class.getName());
+
+   /**
+    * Creates a new instance.
+    * 
+    * @param mcf managed connection factory
+    * @param pc pool configuration
+    * @param noTxSeparatePools notx seperate pool
+    * @param sharable Are the connections sharable
+    * @param mcp mcp
+    */
+   public OnePool(final ManagedConnectionFactory mcf, final PoolConfiguration pc,
+                  final boolean noTxSeparatePools, final boolean sharable,
+                  final String mcp)
+   {
+      super(mcf, pc, noTxSeparatePools, sharable, mcp);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected Object getKey(final Subject subject, final ConnectionRequestInfo cri, boolean separateNoTx)
+   {
+      if (separateNoTx)
+      {
+         return Boolean.TRUE;
+      }
+      else
+      {
+         return Boolean.FALSE;
+      }
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public void emptyManagedConnectionPool(ManagedConnectionPool pool)
+   {
+      // No-operation
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean testConnection()
+   {
+      return internalTestConnection(null, null);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean testConnection(ConnectionRequestInfo cri, Subject subject)
+   {
+      return internalTestConnection(null, null);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public CoreLogger getLogger()
+   {
+      return log;
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/PoolByCri.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/PoolByCri.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/PoolByCri.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,94 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2008-2009, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager.pool.strategy;
+
+import org.jboss.jca.core.CoreLogger;
+import org.jboss.jca.core.api.connectionmanager.pool.PoolConfiguration;
+import org.jboss.jca.core.connectionmanager.pool.AbstractPool;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.ConnectionRequestInfo;
+import javax.resource.spi.ManagedConnectionFactory;
+import javax.security.auth.Subject;
+
+import org.jboss.logging.Logger;
+
+/**
+ * Pool implementation that uses subject.
+ * 
+ * @author Gurkan Erdogdu 
+ * @author Jesper Pedersen 
+ */
+public class PoolByCri extends AbstractPool
+{
+   /** The logger */
+   private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, PoolByCri.class.getName());
+   
+   /**
+    * Creates a new instance.
+    * @param mcf managed connection factory
+    * @param pc pool configuration
+    * @param noTxSeparatePools notx seperate pool
+    * @param sharable Are the connections sharable
+    * @param mcp mcp
+    */
+   public PoolByCri(final ManagedConnectionFactory mcf, final PoolConfiguration pc,
+                    final boolean noTxSeparatePools, final boolean sharable,
+                    final String mcp)
+   {
+      super(mcf, pc, noTxSeparatePools, sharable, mcp);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected Object getKey(Subject subject, ConnectionRequestInfo cri, boolean separateNoTx) throws ResourceException
+   {
+      return new CriKey(cri, separateNoTx);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean testConnection()
+   {
+      return false;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean testConnection(ConnectionRequestInfo cri, Subject subject)
+   {
+      return internalTestConnection(cri, null);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public CoreLogger getLogger()
+   {
+      return log;
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/PoolBySubject.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/PoolBySubject.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/PoolBySubject.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,164 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2008-2009, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager.pool.strategy;
+
+import org.jboss.jca.core.CoreLogger;
+import org.jboss.jca.core.api.connectionmanager.pool.PoolConfiguration;
+import org.jboss.jca.core.connectionmanager.ConnectionManager;
+import org.jboss.jca.core.connectionmanager.pool.AbstractPrefillPool;
+import org.jboss.jca.core.spi.security.SubjectFactory;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Set;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.ConnectionRequestInfo;
+import javax.resource.spi.ManagedConnectionFactory;
+import javax.resource.spi.security.PasswordCredential;
+import javax.security.auth.Subject;
+
+import org.jboss.logging.Logger;
+
+/**
+ * Pool implementation that uses subject.
+ * 
+ * @author Gurkan Erdogdu 
+ * @author Jesper Pedersen 
+ */
+public class PoolBySubject extends AbstractPrefillPool
+{
+   /** The logger */
+   private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, PoolBySubject.class.getName());
+   
+   /**
+    * Creates a new instance.
+    * @param mcf managed connection factory
+    * @param pc pool configuration
+    * @param noTxSeparatePools notx seperate pool
+    * @param sharable Are the connections sharable
+    * @param mcp mcp
+    */
+   public PoolBySubject(final ManagedConnectionFactory mcf, final PoolConfiguration pc,
+                        final boolean noTxSeparatePools, final boolean sharable,
+                        final String mcp)
+   {
+      super(mcf, pc, noTxSeparatePools, sharable, mcp);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected Object getKey(Subject subject, ConnectionRequestInfo cri, boolean separateNoTx) throws ResourceException
+   {
+      return new SubjectKey(subject, separateNoTx);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean testConnection()
+   {
+      try
+      {
+         ConnectionManager cm = getConnectionManager();
+         ManagedConnectionFactory mcf = getManagedConnectionFactory();
+       
+         Subject subject = createSubject(cm.getSubjectFactory(), cm.getSecurityDomain(), mcf, cm.getJndiName());
+  
+         if (subject != null)
+            return internalTestConnection(null, subject);
+      }
+      catch (Throwable t)
+      {
+         log.debugf(t, "Error during testConnection: %s", t.getMessage());
+      }
+
+      return false;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean testConnection(ConnectionRequestInfo cri, Subject subject)
+   {
+      return internalTestConnection(null, subject);
+   }
+
+   /**
+    * Create a subject
+    * @param subjectFactory The subject factory
+    * @param securityDomain The security domain
+    * @param mcf The managed connection factory
+    * @param jndiName The jndi-name
+    * @return The subject; null in case of an error
+    */
+   protected Subject createSubject(final SubjectFactory subjectFactory,
+                                   final String securityDomain,
+                                   final ManagedConnectionFactory mcf,
+                                   final String jndiName)
+   {
+      if (subjectFactory == null)
+         throw new IllegalArgumentException("SubjectFactory is null");
+
+      if (securityDomain == null)
+         throw new IllegalArgumentException("SecurityDomain is null");
+
+      return AccessController.doPrivileged(new PrivilegedAction() 
+      {
+         public Subject run()
+         {
+            try
+            {
+               Subject subject = subjectFactory.createSubject(securityDomain);
+
+               Set pcs = subject.getPrivateCredentials(PasswordCredential.class);
+               if (pcs.size() > 0)
+               {
+                  for (PasswordCredential pc : pcs)
+                  {
+                     pc.setManagedConnectionFactory(mcf);
+                  }
+               }
+
+               return subject;
+            }
+            catch (Throwable t)
+            {
+               log.exceptionDuringCreateSubject(jndiName, t.getMessage(), t);
+            }
+
+            return null;
+         }
+      });
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public CoreLogger getLogger()
+   {
+      return log;
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/PoolBySubjectAndCri.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/PoolBySubjectAndCri.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/PoolBySubjectAndCri.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,95 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2008-2009, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager.pool.strategy;
+
+import org.jboss.jca.core.CoreLogger;
+import org.jboss.jca.core.api.connectionmanager.pool.PoolConfiguration;
+import org.jboss.jca.core.connectionmanager.pool.AbstractPool;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.ConnectionRequestInfo;
+import javax.resource.spi.ManagedConnectionFactory;
+import javax.security.auth.Subject;
+
+import org.jboss.logging.Logger;
+
+/**
+ * Pool implementation that uses subject and connection
+ * request info for its pool partition.
+ * 
+ * @author Gurkan Erdogdu 
+ * @author Jesper Pedersen 
+ */
+public class PoolBySubjectAndCri extends AbstractPool
+{
+   /** The logger */
+   private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, PoolBySubjectAndCri.class.getName());
+   
+   /**
+    * Creates a new instance.
+    * @param mcf managed connection factory
+    * @param pc pool configuration
+    * @param noTxSeparatePools notx seperate pool
+    * @param sharable Are the connections sharable
+    * @param mcp mcp
+    */
+   public PoolBySubjectAndCri(final ManagedConnectionFactory mcf, final PoolConfiguration pc,
+                              final boolean noTxSeparatePools, final boolean sharable,
+                              final String mcp)
+   {
+      super(mcf, pc, noTxSeparatePools, sharable, mcp);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected Object getKey(Subject subject, ConnectionRequestInfo cri, boolean separateNoTx) throws ResourceException
+   {
+      return new SubjectCriKey(subject, cri, separateNoTx);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean testConnection()
+   {
+      return false;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean testConnection(ConnectionRequestInfo cri, Subject subject)
+   {
+      return internalTestConnection(cri, subject);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public CoreLogger getLogger()
+   {
+      return log;
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/ReauthKey.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/ReauthKey.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/ReauthKey.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,76 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2011, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager.pool.strategy;
+
+import javax.resource.spi.ConnectionRequestInfo;
+import javax.security.auth.Subject;
+
+/**
+ * Simple reauth pool with same properties as an OnePool
+ * @author Jesper Pedersen  
+ */
+class ReauthKey
+{
+   /** The cached hashCode */
+   private int hashCode = Integer.MAX_VALUE;
+
+   /**
+    * Constructor
+    * @param subject subject instance
+    * @param cri connection request info
+    * @param separateNoTx seperateNoTx
+    */
+   ReauthKey(Subject subject, ConnectionRequestInfo cri, boolean separateNoTx)
+   {
+      this.hashCode = separateNoTx ? Boolean.TRUE.hashCode() : Boolean.FALSE.hashCode();
+   }
+   
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public int hashCode()
+   {
+      return hashCode;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public boolean equals(Object obj)
+   {
+      if (this == obj)
+      {
+         return true;  
+      }
+      
+      if (obj == null || !(obj instanceof ReauthKey))
+      {
+         return false;  
+      }
+      
+      ReauthKey other = (ReauthKey)obj;
+      return hashCode == other.hashCode;
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/ReauthPool.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/ReauthPool.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/ReauthPool.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,110 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2008-2009, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager.pool.strategy;
+
+import org.jboss.jca.core.CoreLogger;
+import org.jboss.jca.core.api.connectionmanager.pool.PoolConfiguration;
+import org.jboss.jca.core.connectionmanager.pool.AbstractPool;
+import org.jboss.jca.core.connectionmanager.pool.mcp.ManagedConnectionPool;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.ConnectionRequestInfo;
+import javax.resource.spi.ManagedConnectionFactory;
+import javax.security.auth.Subject;
+
+import org.jboss.logging.Logger;
+
+/**
+ * Pool implementation that supports reauthentication
+ *
+ * @author Jesper Pedersen 
+ */
+public class ReauthPool extends AbstractPool
+{
+   /** The logger */
+   private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, ReauthPool.class.getName());
+
+   /**
+    * Creates a new instance.
+    * @param mcf managed connection factory
+    * @param pc pool configuration
+    * @param noTxSeparatePools notx seperate pool
+    * @param sharable Are the connections sharable
+    * @param mcp mcp
+    */
+   public ReauthPool(final ManagedConnectionFactory mcf,
+                     final PoolConfiguration pc,
+                     final boolean noTxSeparatePools,
+                     final boolean sharable,
+                     final String mcp)
+   {
+      super(mcf, pc, noTxSeparatePools, sharable, mcp);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected synchronized Object getKey(Subject subject, ConnectionRequestInfo cri, boolean separateNoTx)
+      throws ResourceException
+   {
+      return new ReauthKey(subject, cri, separateNoTx);
+   }
+
+   /**
+    * There is no reason to empty the managed connection pool for reauth enabled
+    * resource adapters, since all managed connections can change
+    * its credentials
+    * 
+    * @param pool the managed connection pool
+    */
+   @Override
+   public void emptyManagedConnectionPool(ManagedConnectionPool pool)
+   {
+      // No-operation
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean testConnection()
+   {
+      return false;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public boolean testConnection(ConnectionRequestInfo cri, Subject subject)
+   {
+      return internalTestConnection(cri, subject);
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   public CoreLogger getLogger()
+   {
+      return log;
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/SecurityActions.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/SecurityActions.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/SecurityActions.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,85 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2010, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager.pool.strategy;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import javax.security.auth.Subject;
+
+/**
+ * Privileged Blocks
+ * @author Jesper Pedersen 
+ */
+class SecurityActions
+{ 
+   /**
+    * Constructor
+    */
+   private SecurityActions()
+   {
+   }
+
+   /**
+    * Get the hash code for a Subject
+    * @param subject The Subject
+    * @return The hash code
+    */
+   static int hashCode(final Subject subject)
+   {
+      if (System.getSecurityManager() == null)
+         return subject.hashCode();
+
+      Integer hashCode = AccessController.doPrivileged(new PrivilegedAction() 
+      {
+         public Integer run()
+         {
+            return subject.hashCode();
+         }
+      });
+
+      return hashCode.intValue();
+   }
+
+   /**
+    * Verify if two Subject's are equal
+    * @param s1 The first Subject
+    * @param s2 The second Subject
+    * @return True if equal; otherwise false
+    */
+   static boolean equals(final Subject s1, final Subject s2)
+   {
+      if (System.getSecurityManager() == null)
+         return s1 != null ? s1.equals(s2) : s2 == null;
+
+      Boolean equals = AccessController.doPrivileged(new PrivilegedAction() 
+      {
+         public Boolean run()
+         {
+            return s1 != null ? s1.equals(s2) : s2 == null;
+         }
+      });
+
+      return equals.booleanValue();
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/SubjectCriKey.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/SubjectCriKey.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/SubjectCriKey.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,108 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2008-2009, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager.pool.strategy;
+
+import javax.resource.spi.ConnectionRequestInfo;
+import javax.security.auth.Subject;
+
+/**
+ * Pool key based on {@link Subject} and {@link ConnectionRequestInfo}.
+ * 
+ * @author Gurkan Erdogdu 
+ * @author David Jencks 
+ * @author Adrian Brock 
+ * @author Weston Price 
+ * @author Jesper Pedersen  
+ * @version $Rev: $
+ */
+class SubjectCriKey
+{
+   /** Identifies no subject */
+   private static final Subject NOSUBJECT = new Subject();
+   
+   /** Identifies no connection request information */
+   private static final Object NOCRI = new Object();
+
+   /** The subject */
+   private final Subject subject;
+   
+   /** The connection request information */
+   private final Object cri;
+   
+   /** The cached hashCode */
+   private int hashCode = Integer.MAX_VALUE;
+
+   /** Separate no tx */
+   private boolean separateNoTx;
+
+   /**
+    * 
+    * @param subject subject instance
+    * @param cri connection request info
+    * @param separateNoTx seperateNoTx
+    */
+   SubjectCriKey(Subject subject, ConnectionRequestInfo cri, boolean separateNoTx)
+   {
+      this.subject = (subject == null) ? NOSUBJECT : subject;
+      this.cri = (cri == null) ? NOCRI : cri;
+      this.separateNoTx = separateNoTx;
+   }
+   
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public int hashCode()
+   {
+      if (hashCode == Integer.MAX_VALUE)
+      {
+         hashCode = SecurityActions.hashCode(subject) ^ cri.hashCode();  
+      }
+      
+      return hashCode;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public boolean equals(Object obj)
+   {
+      if (this == obj)
+      {
+         return true;  
+      }
+      
+      if (obj == null || !(obj instanceof SubjectCriKey))
+      {
+         return false;  
+      }
+      
+      SubjectCriKey other = (SubjectCriKey) obj;
+      
+      return SecurityActions.equals(subject, other.subject) 
+         && cri.equals(other.cri)
+         && separateNoTx == other.separateNoTx;
+   }
+
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/SubjectKey.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/SubjectKey.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/SubjectKey.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,90 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2008-2009, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager.pool.strategy;
+
+import javax.security.auth.Subject;
+
+/**
+ * Pool by {@link Subject} key.
+ * 
+ * @author Gurkan Erdogdu 
+ * @version $Rev: $
+ */
+class SubjectKey
+{
+   /** Identifies no subject */
+   private static final Subject NOSUBJECT = new Subject();
+
+   /** The subject */
+   private final Subject subject;
+
+   /** Separate no tx */
+   private boolean separateNoTx;
+   
+   /** The cached hashCode */
+   private int hashCode = Integer.MAX_VALUE;
+
+   /**
+    * Creates a new instance.
+    * @param subject subject 
+    * @param separateNoTx separateNoTx
+    */
+   SubjectKey(Subject subject, boolean separateNoTx)
+   {
+      this.subject = (subject == null) ? NOSUBJECT : subject;
+      this.separateNoTx = separateNoTx;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public int hashCode()
+   {
+      if (hashCode == Integer.MAX_VALUE)
+         hashCode = SecurityActions.hashCode(subject);
+
+      return hashCode;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public boolean equals(Object obj)
+   {
+      if (this == obj)
+      {
+         return true;  
+      }
+      if (obj == null || !(obj instanceof SubjectKey))
+      {
+         return false;  
+      }
+      SubjectKey other = (SubjectKey) obj;
+      
+      return SecurityActions.equals(subject, other.subject)
+         && separateNoTx == other.separateNoTx;
+   }
+   
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/package.html
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/package.html	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/strategy/package.html	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,3 @@
+
+This package contains the connection pool strategies.
+
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/validator/ConnectionValidator.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/validator/ConnectionValidator.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/validator/ConnectionValidator.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,308 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2008-2011, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager.pool.validator;
+
+import org.jboss.jca.core.CoreLogger;
+import org.jboss.jca.core.connectionmanager.pool.mcp.ManagedConnectionPool;
+
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.jboss.logging.Logger;
+
+/**
+ * Connection validator
+ * 
+ * @author Gurkan Erdogdu 
+ * @author Jesper Pedersen 
+ */
+public class ConnectionValidator
+{
+   /** Logger instance */
+   private static CoreLogger logger = Logger.getMessageLogger(CoreLogger.class, ConnectionValidator.class.getName());
+   
+   /** Thread name */
+   private static final String THREAD_NAME = "ConnectionValidator";
+   
+   /** Singleton instance */
+   private static ConnectionValidator instance = new ConnectionValidator();
+   
+   /** Registered pool instances */
+   private CopyOnWriteArrayList registeredPools = 
+      new CopyOnWriteArrayList();
+   
+   /** Executor service */
+   private ExecutorService executorService;
+
+   /** Is the executor external */
+   private boolean isExternal;
+   
+   /** The interval */
+   private long interval;
+
+   /** The next scan */
+   private long next;
+   
+   /** Shutdown */
+   private AtomicBoolean shutdown;
+
+   /** Lock */
+   private Lock lock;
+   
+   /** Condition */
+   private Condition condition;
+   
+   /**
+    * Private constructor.
+    */
+   private ConnectionValidator()
+   {
+      this.executorService = null;
+      this.isExternal = false;
+      this.interval = Long.MAX_VALUE;
+      this.next = Long.MAX_VALUE;
+      this.shutdown = new AtomicBoolean(false);
+      this.lock = new ReentrantLock(true);
+      this.condition = lock.newCondition();
+   }
+
+   /**
+    * Get the instance
+    * @return The value
+    */
+   public static ConnectionValidator getInstance()
+   {
+      return instance;
+   }
+   
+   /**
+    * Set the executor service
+    * @param v The value
+    */
+   public void setExecutorService(ExecutorService v)
+   {
+      if (v != null)
+      {
+         this.executorService = v;
+         this.isExternal = true;
+      }
+      else
+      {
+         this.executorService = null;
+         this.isExternal = false;
+      }
+   }
+
+   /**
+    * Start
+    * @exception Throwable Thrown if an error occurs
+    */
+   public void start() throws Throwable
+   {
+      if (!isExternal)
+      {
+         this.executorService = Executors.newSingleThreadExecutor(new ValidatorThreadFactory());
+      }
+
+      this.shutdown.set(false);
+      this.interval = Long.MAX_VALUE;
+      this.next = Long.MAX_VALUE;
+
+      this.executorService.execute(new ConnectionValidatorRunner());
+   }
+
+   /**
+    * Stop
+    * @exception Throwable Thrown if an error occurs
+    */
+   public void stop() throws Throwable
+   {
+      instance.shutdown.set(true);
+
+      if (!isExternal)
+      {
+         instance.executorService.shutdownNow();
+         instance.executorService = null;
+      }
+
+      instance.registeredPools.clear();
+   }
+   
+   /**
+    * Register pool for connection validation.
+    * @param mcp managed connection pool
+    * @param interval validation interval
+    */
+   public void registerPool(ManagedConnectionPool mcp, long interval)
+   {
+      logger.debugf("Register pool: %s (interval=%s)", mcp, interval);
+
+      instance.internalRegisterPool(mcp, interval);
+   }
+   
+   /**
+    * Unregister pool instance for connection validation.
+    * @param mcp pool instance
+    */
+   public void unregisterPool(ManagedConnectionPool mcp)
+   {
+      logger.debugf("Unregister pool: %s", mcp);
+
+      instance.internalUnregisterPool(mcp);
+   }
+   
+   private void internalRegisterPool(ManagedConnectionPool mcp, long interval)
+   {
+      try
+      {
+         this.lock.lock();
+         
+         this.registeredPools.addIfAbsent(mcp);
+         
+         if (interval > 1 && interval / 2 < this.interval) 
+         {
+            this.interval = interval / 2;
+            long maybeNext = System.currentTimeMillis() + this.interval;
+            if (next > maybeNext && maybeNext > 0) 
+            {
+               next = maybeNext;
+               if (logger.isDebugEnabled())
+               {
+                  logger.debug("About to notify thread: old next: " + next + ", new next: " + maybeNext);
+               }               
+               
+               this.condition.signal();
+            }
+         }
+      } 
+      finally
+      {
+         this.lock.unlock();
+      }
+   }
+   
+   private void internalUnregisterPool(ManagedConnectionPool mcp)
+   {
+      this.registeredPools.remove(mcp);
+      
+      if (this.registeredPools.size() == 0) 
+      {
+         if (logger.isDebugEnabled())
+         {
+            logger.debug("Setting interval to Long.MAX_VALUE");  
+         }
+         
+         interval = Long.MAX_VALUE;
+      }
+   }
+
+   /**
+    * Thread factory.
+    */
+   private static class ValidatorThreadFactory implements ThreadFactory
+   {
+      /**
+       * {@inheritDoc}
+       */
+      public Thread newThread(Runnable r)
+      {
+         Thread thread = new Thread(r, ConnectionValidator.THREAD_NAME);
+         thread.setDaemon(true);
+         
+         return thread;
+      }      
+   }
+   
+   /**
+    * ConnectionValidatorRunner.
+    *
+    */
+   private class ConnectionValidatorRunner implements Runnable
+   {
+      /**
+       * {@inheritDoc}
+       */
+      public void run()
+      {
+         final ClassLoader oldTccl = SecurityActions.getThreadContextClassLoader();
+         SecurityActions.setThreadContextClassLoader(ConnectionValidator.class.getClassLoader());
+         
+         try
+         {
+            lock.lock();
+            
+            while (!shutdown.get())
+            {
+               boolean result = instance.condition.await(instance.interval, TimeUnit.MILLISECONDS);
+               
+               if (logger.isTraceEnabled())
+               {
+                  logger.trace("Result of await: " + result);
+               }
+               
+               if (logger.isDebugEnabled())
+               {
+                  logger.debug("Notifying pools, interval: " + interval);  
+               }
+     
+               for (ManagedConnectionPool mcp : registeredPools)
+               {
+                  mcp.validateConnections();
+               }
+
+               next = System.currentTimeMillis() + interval;
+               
+               if (next < 0)
+               {
+                  next = Long.MAX_VALUE;  
+               }              
+            }            
+         }
+         catch (InterruptedException e)
+         {
+            if (!shutdown.get())
+               logger.returningConnectionValidatorInterrupted();
+         }
+         catch (RuntimeException e)
+         {
+            logger.connectionValidatorIgnoredUnexpectedRuntimeException(e);
+         }
+         catch (Exception e)
+         {
+            logger.connectionValidatorIgnoredUnexpectedError(e);
+         }         
+         finally
+         {
+            lock.unlock();  
+            SecurityActions.setThreadContextClassLoader(oldTccl);
+         }
+      }
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/validator/SecurityActions.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/validator/SecurityActions.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/validator/SecurityActions.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,83 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2008, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors. 
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jca.core.connectionmanager.pool.validator;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Privileged Blocks
+ * 
+ * @author Jesper Pedersen 
+ */
+class SecurityActions
+{
+   /**
+    * Get the context classloader.
+    * @return The classloader
+    */
+   public static ClassLoader getThreadContextClassLoader()
+   {
+      if (System.getSecurityManager() == null)
+      {
+         return Thread.currentThread().getContextClassLoader();
+      }
+      else
+      {
+         return AccessController.doPrivileged(new PrivilegedAction()
+         {
+            public ClassLoader run()
+            {
+               return Thread.currentThread().getContextClassLoader();
+            }
+         });
+      }
+   }
+
+   /**
+    * Set the context classloader.
+    * @param cl classloader
+    */
+   public static void setThreadContextClassLoader(final ClassLoader cl)
+   {
+      if (cl == null)
+         return;
+
+      if (System.getSecurityManager() == null)
+      {
+         Thread.currentThread().setContextClassLoader(cl);
+      }
+      else
+      {
+         AccessController.doPrivileged(new PrivilegedAction()
+         {
+            public Object run()
+            {
+               Thread.currentThread().setContextClassLoader(cl);
+
+               return null;
+            }
+         });
+      }
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/validator/package.html
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/validator/package.html	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/pool/validator/package.html	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,3 @@
+
+This package contains the connection validator logic.
+
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/transaction/LockKey.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/transaction/LockKey.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/transaction/LockKey.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,65 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2011, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager.transaction;
+
+/**
+ * Defines the lock key 
+ * 
+ * @author Jesper Pedersen 
+ */
+public class LockKey
+{
+   /** Instance */
+   public static final LockKey INSTANCE = new LockKey();
+
+   /**
+    * Constructor
+    */
+   private LockKey()
+   {
+   }
+
+   /**
+    * Equals
+    * @param other The other object
+    * @return True if equal; otherwise false
+    */
+   public boolean equals(Object other)
+   {
+      if (this == other)
+         return true;
+
+      if (other == null || !(other instanceof LockKey))
+         return false;
+
+      return true;
+   }
+
+   /**
+    * Hash code
+    * @return The value
+    */
+   public int hashCode()
+   {
+      return 42;
+   }
+}
Index: 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/transaction/TransactionSynchronizer.java
===================================================================
diff -u
--- 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/transaction/TransactionSynchronizer.java	(revision 0)
+++ 3rdParty_sources/ironjacamar/org/jboss/jca/core/connectionmanager/transaction/TransactionSynchronizer.java	(revision 8b7897a917497532f0074f6a38c6ded6fd94cdb9)
@@ -0,0 +1,501 @@
+/*
+ * IronJacamar, a Java EE Connector Architecture implementation
+ * Copyright 2006, Red Hat Inc, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.connectionmanager.transaction;
+
+import org.jboss.jca.core.CoreLogger;
+import org.jboss.jca.core.spi.transaction.TransactionIntegration;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import javax.transaction.RollbackException;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+
+import org.jboss.logging.Logger;
+
+/**
+ * Organizes transaction synchronization done by JCA.
+ * 
+ *  
+ * This class exists to make sure all Tx synchronizations
+ * are invoked before the cached connection manager closes any
+ * closed connections.
+ *
+ * @author Adrian Brock 
+ * @author gurkanerdogdu
+ * @version $Rev$
+ */
+public class TransactionSynchronizer implements Synchronization
+{
+   /** The logger */
+   private static CoreLogger log = Logger.getMessageLogger(CoreLogger.class, TransactionSynchronizer.class.getName());
+
+   /** The records */
+   private static ConcurrentMap records =
+      new ConcurrentHashMap(512, 0.75f, 512);
+   
+   /** The transaction */
+   private Transaction tx;
+
+   /** The identifier */
+   private Object identifier;
+   
+   /** The enlisting thread */
+   private Thread enlistingThread;
+   
+   /** Unenlisted */
+   private List unenlisted;
+   
+   /** Enlisted */
+   private List enlisted;
+   
+   /** The cached connection manager synchronization */
+   private Synchronization ccmSynch;
+   
+   /**
+    * Create a new transaction synchronizer
+    * 
+    * @param tx the transaction to synchronize with
+    * @param id the identifier for the transaction
+    */
+   private TransactionSynchronizer(Transaction tx, Object id)
+   {
+      this.tx = tx;
+      this.identifier = id;
+      this.enlistingThread = null;
+      this.unenlisted = new ArrayList(1);
+      this.enlisted = new ArrayList(1);
+   }
+   
+   /**
+    * Add a new Tx synchronization that has not been enlisted
+    * 
+    * @param synch the synchronization
+    */
+   public synchronized void addUnenlisted(Synchronization synch)
+   {
+      if (unenlisted == null)
+         unenlisted = new ArrayList