diff --git a/src/main/java/com/zaxxer/hikari/HikariConfig.java b/src/main/java/com/zaxxer/hikari/HikariConfig.java
index 97310a36..d8557b03 100644
--- a/src/main/java/com/zaxxer/hikari/HikariConfig.java
+++ b/src/main/java/com/zaxxer/hikari/HikariConfig.java
@@ -29,6 +29,7 @@ import javax.sql.DataSource;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.zaxxer.hikari.proxy.JavassistProxyFactory;
 import com.zaxxer.hikari.util.PropertyBeanSetter;
 
 public final class HikariConfig implements HikariConfigMBean
@@ -64,6 +65,11 @@ public final class HikariConfig implements HikariConfigMBean
     private Properties dataSourceProperties;
     private DataSource dataSource;
 
+    static
+    {
+        JavassistProxyFactory.initialize();
+    }
+
     /**
      * Default constructor
      */
diff --git a/src/main/java/com/zaxxer/hikari/HikariPool.java b/src/main/java/com/zaxxer/hikari/HikariPool.java
index 966da0be..e4b9aef7 100644
--- a/src/main/java/com/zaxxer/hikari/HikariPool.java
+++ b/src/main/java/com/zaxxer/hikari/HikariPool.java
@@ -32,7 +32,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.zaxxer.hikari.proxy.IHikariConnectionProxy;
-import com.zaxxer.hikari.proxy.JavassistProxyFactoryFactory;
+import com.zaxxer.hikari.proxy.ProxyFactory;
 import com.zaxxer.hikari.util.PropertyBeanSetter;
 
 /**
@@ -325,7 +325,7 @@ public final class HikariPool implements HikariPoolMBean
             try
             {
                 Connection connection = dataSource.getConnection();
-                IHikariConnectionProxy proxyConnection = (IHikariConnectionProxy) JavassistProxyFactoryFactory.getProxyFactory().getProxyConnection(this, connection);
+                IHikariConnectionProxy proxyConnection = (IHikariConnectionProxy) ProxyFactory.getProxyConnection(this, connection);
 
                 if (transactionIsolation < 0)
                 {
diff --git a/src/main/java/com/zaxxer/hikari/proxy/ConnectionProxy.java b/src/main/java/com/zaxxer/hikari/proxy/ConnectionProxy.java
index bbd98cb4..e8885c80 100644
--- a/src/main/java/com/zaxxer/hikari/proxy/ConnectionProxy.java
+++ b/src/main/java/com/zaxxer/hikari/proxy/ConnectionProxy.java
@@ -27,7 +27,7 @@ import java.util.Timer;
 import java.util.TimerTask;
 
 import com.zaxxer.hikari.HikariPool;
-import com.zaxxer.hikari.util.FastList;
+import com.zaxxer.hikari.util.FastStatementList;
 
 /**
  * This is the proxy class for java.sql.Connection.
@@ -36,13 +36,11 @@ import com.zaxxer.hikari.util.FastList;
  */
 public abstract class ConnectionProxy implements IHikariConnectionProxy
 {
-    private static final ProxyFactory PROXY_FACTORY;
-
     private static final Set<String> SQL_ERRORS;
 
     protected final Connection delegate;
 
-    private final FastList<Statement> openStatements;
+    private final FastStatementList openStatements;
     private final HikariPool parentPool;
 
     private boolean isClosed;
@@ -63,8 +61,6 @@ public abstract class ConnectionProxy implements IHikariConnectionProxy
         SQL_ERRORS.add("57P03");  // CANNOT CONNECT NOW
         SQL_ERRORS.add("57P02");  // CRASH SHUTDOWN
         SQL_ERRORS.add("01002");  // SQL92 disconnect error
-
-        PROXY_FACTORY = JavassistProxyFactoryFactory.getProxyFactory();
     }
 
     protected ConnectionProxy(HikariPool pool, Connection connection)
@@ -73,7 +69,7 @@ public abstract class ConnectionProxy implements IHikariConnectionProxy
         this.delegate = connection;
 
         creationTime = lastAccess = System.currentTimeMillis();
-        openStatements = new FastList<Statement>();
+        openStatements = new FastStatementList();
     }
     
     public final void unregisterStatement(Object statement)
@@ -409,61 +405,61 @@ public abstract class ConnectionProxy implements IHikariConnectionProxy
 
     private final Statement __createStatement() throws SQLException
     {
-        return PROXY_FACTORY.getProxyStatement(this, delegate.createStatement());
+        return ProxyFactory.getProxyStatement(this, delegate.createStatement());
     }
 
     private final Statement __createStatement(int resultSetType, int resultSetConcurrency) throws SQLException
     {
-        return PROXY_FACTORY.getProxyStatement(this, delegate.createStatement(resultSetType, resultSetConcurrency));
+        return ProxyFactory.getProxyStatement(this, delegate.createStatement(resultSetType, resultSetConcurrency));
     }
 
     private final Statement __createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException
     {
-        return PROXY_FACTORY.getProxyStatement(this, delegate.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability));
+        return ProxyFactory.getProxyStatement(this, delegate.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability));
     }
 
     private final CallableStatement __prepareCall(String sql) throws SQLException
     {
-        return PROXY_FACTORY.getProxyCallableStatement(this, delegate.prepareCall(sql));
+        return ProxyFactory.getProxyCallableStatement(this, delegate.prepareCall(sql));
     }
 
     private final CallableStatement __prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException
     {
-        return PROXY_FACTORY.getProxyCallableStatement(this, delegate.prepareCall(sql, resultSetType, resultSetConcurrency));
+        return ProxyFactory.getProxyCallableStatement(this, delegate.prepareCall(sql, resultSetType, resultSetConcurrency));
     }
 
     private final CallableStatement __prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException
     {
-        return PROXY_FACTORY.getProxyCallableStatement(this, delegate.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability));
+        return ProxyFactory.getProxyCallableStatement(this, delegate.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability));
     }
 
     private final PreparedStatement __prepareStatement(String sql) throws SQLException
     {
-        return PROXY_FACTORY.getProxyPreparedStatement(this, delegate.prepareStatement(sql));
+        return ProxyFactory.getProxyPreparedStatement(this, delegate.prepareStatement(sql));
     }
 
     private final PreparedStatement __prepareStatement(String sql, int autoGeneratedKeys) throws SQLException
     {
-        return PROXY_FACTORY.getProxyPreparedStatement(this, delegate.prepareStatement(sql, autoGeneratedKeys));
+        return ProxyFactory.getProxyPreparedStatement(this, delegate.prepareStatement(sql, autoGeneratedKeys));
     }
 
     private final PreparedStatement __prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException
     {
-        return PROXY_FACTORY.getProxyPreparedStatement(this, delegate.prepareStatement(sql, resultSetType, resultSetConcurrency));
+        return ProxyFactory.getProxyPreparedStatement(this, delegate.prepareStatement(sql, resultSetType, resultSetConcurrency));
     }
 
     private final PreparedStatement __prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException
     {
-        return PROXY_FACTORY.getProxyPreparedStatement(this, delegate.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability));
+        return ProxyFactory.getProxyPreparedStatement(this, delegate.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability));
     }
 
     private final PreparedStatement __prepareStatement(String sql, int[] columnIndexes) throws SQLException
     {
-        return PROXY_FACTORY.getProxyPreparedStatement(this, delegate.prepareStatement(sql, columnIndexes));
+        return ProxyFactory.getProxyPreparedStatement(this, delegate.prepareStatement(sql, columnIndexes));
     }
 
     private final PreparedStatement __prepareStatement(String sql, String[] columnNames) throws SQLException
     {
-        return PROXY_FACTORY.getProxyPreparedStatement(this, delegate.prepareStatement(sql, columnNames));
+        return ProxyFactory.getProxyPreparedStatement(this, delegate.prepareStatement(sql, columnNames));
     }
 }
diff --git a/src/main/java/com/zaxxer/hikari/proxy/JavassistProxyFactoryFactory.java b/src/main/java/com/zaxxer/hikari/proxy/JavassistProxyFactory.java
similarity index 82%
rename from src/main/java/com/zaxxer/hikari/proxy/JavassistProxyFactoryFactory.java
rename to src/main/java/com/zaxxer/hikari/proxy/JavassistProxyFactory.java
index ac6ae306..ef406ce8 100644
--- a/src/main/java/com/zaxxer/hikari/proxy/JavassistProxyFactoryFactory.java
+++ b/src/main/java/com/zaxxer/hikari/proxy/JavassistProxyFactory.java
@@ -31,16 +31,16 @@ import javassist.CtNewMethod;
 import javassist.LoaderClassPath;
 import javassist.Modifier;
 
+import org.slf4j.LoggerFactory;
+
 import com.zaxxer.hikari.util.ClassLoaderUtils;
 
 /**
  *
  * @author Brett Wooldridge
  */
-public final class JavassistProxyFactoryFactory
+public final class JavassistProxyFactory
 {
-    private static final ProxyFactory proxyFactory;
-
     private ClassPool classPool;
 
     static
@@ -48,11 +48,10 @@ public final class JavassistProxyFactoryFactory
     	ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
         try
         {
-        	Thread.currentThread().setContextClassLoader(JavassistProxyFactoryFactory.class.getClassLoader());
+        	Thread.currentThread().setContextClassLoader(JavassistProxyFactory.class.getClassLoader());
         	
-        	JavassistProxyFactoryFactory proxyFactoryFactory = new JavassistProxyFactoryFactory();
-
-        	proxyFactory = proxyFactoryFactory.generateProxyFactory();
+        	JavassistProxyFactory proxyFactoryFactory = new JavassistProxyFactory();
+        	proxyFactoryFactory.modifyProxyFactory();
         }
         catch (Exception e)
         {
@@ -64,7 +63,12 @@ public final class JavassistProxyFactoryFactory
         }
     }
 
-    private JavassistProxyFactoryFactory()
+    public static void initialize()
+    {
+        // simply invoking this method causes the initialization of this class.
+    }
+
+    private JavassistProxyFactory()
     {
         classPool = new ClassPool();
         classPool.importPackage("java.sql");
@@ -89,51 +93,43 @@ public final class JavassistProxyFactoryFactory
         }
     }
 
-    public static ProxyFactory getProxyFactory()
-    {
-        return proxyFactory;
-    }
-
-    private ProxyFactory generateProxyFactory() throws Exception
+    private void modifyProxyFactory() throws Exception
     {
-        String packageName = ProxyFactory.class.getPackage().getName();
-        CtClass targetCt = classPool.makeClass(packageName + ".JavassistProxyFactory");
-        CtClass superCt = classPool.getCtClass(ProxyFactory.class.getName());
-        targetCt.setSuperclass(superCt);
-        targetCt.setModifiers(Modifier.FINAL);
-
-        for (CtMethod intfMethod : superCt.getDeclaredMethods())
+        String packageName = JavassistProxyFactory.class.getPackage().getName();
+        CtClass proxyCt = classPool.getCtClass("com.zaxxer.hikari.proxy.ProxyFactory");
+        for (CtMethod method : proxyCt.getMethods())
         {
-            CtMethod method = CtNewMethod.copy(intfMethod, targetCt, null);
-
             StringBuilder call = new StringBuilder("{");
             if ("getProxyConnection".equals(method.getName()))
             {
                 call.append("return new ").append(packageName).append(".ConnectionJavassistProxy($$);");
             }
-            if ("getProxyStatement".equals(method.getName()))
+            else if ("getProxyStatement".equals(method.getName()))
             {
                 call.append("return new ").append(packageName).append(".StatementJavassistProxy($$);");
             }
-            if ("getProxyPreparedStatement".equals(method.getName()))
+            else if ("getProxyPreparedStatement".equals(method.getName()))
             {
                 call.append("return new ").append(packageName).append(".PreparedStatementJavassistProxy($$);");
             }
-            if ("getProxyResultSet".equals(method.getName()))
+            else if ("getProxyResultSet".equals(method.getName()))
             {
                 call.append("return $2 != null ? new ").append(packageName).append(".ResultSetJavassistProxy($$) : null;");
             }
-            if ("getProxyCallableStatement".equals(method.getName()))
+            else if ("getProxyCallableStatement".equals(method.getName()))
             {
                 call.append("return new ").append(packageName).append(".CallableStatementJavassistProxy($$);");
             }
+            else
+            {
+                continue;
+            }
+
             call.append('}');
             method.setBody(call.toString());
-            targetCt.addMethod(method);
         }
 
-        Class<?> clazz = targetCt.toClass(classPool.getClassLoader(), null);
-        return (ProxyFactory) clazz.newInstance();
+        proxyCt.toClass(classPool.getClassLoader(), null);
     }
 
     /**
@@ -198,6 +194,11 @@ public final class JavassistProxyFactoryFactory
             }
         }
 
+        if (LoggerFactory.getLogger(getClass()).isDebugEnabled())
+        {
+            targetCt.debugWriteFile(System.getProperty("java.io.tmpdir"));
+        }
+
         return targetCt.toClass(classPool.getClassLoader(), null);
     }
 }
diff --git a/src/main/java/com/zaxxer/hikari/proxy/ProxyFactory.java b/src/main/java/com/zaxxer/hikari/proxy/ProxyFactory.java
index 277e70b0..ba20ab20 100644
--- a/src/main/java/com/zaxxer/hikari/proxy/ProxyFactory.java
+++ b/src/main/java/com/zaxxer/hikari/proxy/ProxyFactory.java
@@ -25,20 +25,39 @@ import java.sql.Statement;
 import com.zaxxer.hikari.HikariPool;
 
 /**
- * This class defines the interface for generating proxies, the
- * real (concrete) class is actually generated by Javassist.
+ * Injected proxy factory class.
  *
  * @author Brett Wooldridge
  */
-public abstract class ProxyFactory
+public final class ProxyFactory
 {
-    public abstract Connection getProxyConnection(HikariPool pool, Connection connection);
-
-    public abstract Statement getProxyStatement(ConnectionProxy connection, Statement statement);
-
-    public abstract CallableStatement getProxyCallableStatement(ConnectionProxy connection, CallableStatement statement);
-
-    public abstract PreparedStatement getProxyPreparedStatement(ConnectionProxy connection, PreparedStatement statement);
-
-    public abstract ResultSet getProxyResultSet(StatementProxy statement, ResultSet resultSet);
+    public static Connection getProxyConnection(HikariPool pool, Connection connection)
+    {
+        // Body is injected by JavassistProxyFactory
+        return null;
+    }
+
+    static Statement getProxyStatement(ConnectionProxy connection, Statement statement)
+    {
+        // Body is injected by JavassistProxyFactory
+        return null;
+    }
+
+    static CallableStatement getProxyCallableStatement(ConnectionProxy connection, CallableStatement statement)
+    {
+        // Body is injected by JavassistProxyFactory
+        return null;
+    }
+
+    static PreparedStatement getProxyPreparedStatement(ConnectionProxy connection, PreparedStatement statement)
+    {
+        // Body is injected by JavassistProxyFactory
+        return null;
+    }
+
+    static ResultSet getProxyResultSet(StatementProxy statement, ResultSet resultSet)
+    {
+        // Body is injected by JavassistProxyFactory
+        return null;
+    }
 }
diff --git a/src/main/java/com/zaxxer/hikari/proxy/StatementProxy.java b/src/main/java/com/zaxxer/hikari/proxy/StatementProxy.java
index 183b705c..056d3c4a 100644
--- a/src/main/java/com/zaxxer/hikari/proxy/StatementProxy.java
+++ b/src/main/java/com/zaxxer/hikari/proxy/StatementProxy.java
@@ -28,18 +28,11 @@ import java.sql.Statement;
  */
 public abstract class StatementProxy implements Statement
 {
-    protected static final ProxyFactory PROXY_FACTORY;
-
     protected final IHikariConnectionProxy connection;
     protected final Statement delegate;
 
     private boolean isClosed;
     
-    static
-    {
-        PROXY_FACTORY = JavassistProxyFactoryFactory.getProxyFactory();
-    }
-
     protected StatementProxy(IHikariConnectionProxy connection, Statement statement)
     {
         this.connection = connection;
@@ -55,7 +48,7 @@ public abstract class StatementProxy implements Statement
     {
         if (resultSet != null)
         {
-            return PROXY_FACTORY.getProxyResultSet(this, resultSet);
+            return ProxyFactory.getProxyResultSet(this, resultSet);
         }
 
         return null;        
diff --git a/src/main/java/com/zaxxer/hikari/util/FastList.java b/src/main/java/com/zaxxer/hikari/util/FastStatementList.java
similarity index 85%
rename from src/main/java/com/zaxxer/hikari/util/FastList.java
rename to src/main/java/com/zaxxer/hikari/util/FastStatementList.java
index d89f2d4c..f919fb6f 100644
--- a/src/main/java/com/zaxxer/hikari/util/FastList.java
+++ b/src/main/java/com/zaxxer/hikari/util/FastStatementList.java
@@ -16,24 +16,26 @@
 
 package com.zaxxer.hikari.util;
 
+import java.sql.Statement;
+
 
 /**
  * Fast list without range checking.
  *
  * @author Brett Wooldridge
  */
-public class FastList<E>
+public final class FastStatementList
 {
-    private transient Object[] elementData;
+    private Statement[] elementData;
 
     private int size;
 
     /**
      * Construct a FastList with a default size of 16.
      */
-    public FastList()
+    public FastStatementList()
     {
-        this.elementData = new Object[16];
+        this.elementData = new Statement[16];
     }
 
     /**
@@ -41,9 +43,9 @@ public class FastList<E>
      *
      * @param size the initial size of the FastList
      */
-    public FastList(int size)
+    public FastStatementList(int size)
     {
-        this.elementData = new Object[size];
+        this.elementData = new Statement[size];
     }
 
     /**
@@ -51,7 +53,7 @@ public class FastList<E>
      *
      * @param element the element to add
      */
-    public void add(E element)
+    public void add(Statement element)
     {
         if (size < elementData.length)
         {
@@ -62,7 +64,7 @@ public class FastList<E>
             // overflow-conscious code
             int oldCapacity = elementData.length;
             int newCapacity = oldCapacity + (oldCapacity >> 1);
-            Object[] newElementData = new Object[newCapacity];
+            Statement[] newElementData = new Statement[newCapacity];
             System.arraycopy(element, 0, newElementData, 0, oldCapacity);
             newElementData[size++] = element;
             elementData = newElementData;
@@ -75,15 +77,15 @@ public class FastList<E>
      * @param index the index of the element to get
      * @return the element, or ArrayIndexOutOfBounds is thrown if the index is invalid
      */
-    @SuppressWarnings("unchecked")
-    public E get(int index)
+    public Statement get(int index)
     {
-        return (E) elementData[index];
+        return elementData[index];
     }
 
     /**
      * This remove method is most efficient when the element being removed
      * is the last element.  Equality is identity based, not equals() based.
+     * Only the first matching element is removed.
      *
      * @param element the element to remove
      */