Added: Injectors created by the @Guice annotation are now shared at the <test> level
diff --git a/CHANGES.txt b/CHANGES.txt
index fb6ba86..b56a146 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -2,6 +2,8 @@
 
 Added: xmlpathinjar to the TestNG ant task
 Added: TestNG can now invoke package protected constructors
+Added: Injectors created by the @Guice annotation are now shared at the <test> level
+Fixed: https://github.com/cbeust/testng/issues/57 Allow usage of package protected constructor of test classes
 
 ===========================================================================
 
diff --git a/src/main/java/org/testng/ITestContext.java b/src/main/java/org/testng/ITestContext.java
index d5f0ed3..ccb68cf 100644
--- a/src/main/java/org/testng/ITestContext.java
+++ b/src/main/java/org/testng/ITestContext.java
@@ -1,9 +1,13 @@
 package org.testng;
 
+import com.google.inject.Injector;
+import com.google.inject.Module;
+
 import org.testng.xml.XmlTest;
 
 import java.util.Collection;
 import java.util.Date;
+import java.util.List;
 
 
 /**
@@ -112,4 +116,10 @@
    * @return the current XmlTest.
    */
   public XmlTest getCurrentXmlTest();
+
+  public List<Module> getGuiceModules(Class<? extends Module> cls);
+  public void addGuiceModule(Class<? extends Module> cls, Module module);
+
+  public Injector getInjector(List<Module> moduleInstances);
+  public void addInjector(List<Module> moduleInstances, Injector injector);
 }
diff --git a/src/main/java/org/testng/TestRunner.java b/src/main/java/org/testng/TestRunner.java
index f8c7924..ae12022 100644
--- a/src/main/java/org/testng/TestRunner.java
+++ b/src/main/java/org/testng/TestRunner.java
@@ -1,5 +1,8 @@
 package org.testng;
 
+import com.google.inject.Injector;
+import com.google.inject.Module;
+
 import org.testng.collections.Lists;
 import org.testng.collections.Maps;
 import org.testng.internal.Attributes;
@@ -57,7 +60,9 @@
  *
  * @author Cedric Beust, Apr 26, 2004
  */
-public class TestRunner implements ITestContext, ITestResultNotifier, IThreadWorkerFactory<ITestNGMethod> {
+public class TestRunner
+    implements ITestContext, ITestResultNotifier, IThreadWorkerFactory<ITestNGMethod>
+{
   /* generated */
   private static final long serialVersionUID = 4247820024988306670L;
   private ISuite m_suite;
@@ -1797,4 +1802,34 @@
     return m_attributes.removeAttribute(name);
   }
 
+  private Map<Class<? extends Module>, List<Module>> m_guiceModules = Maps.newHashMap();
+
+  @Override
+  public List<Module> getGuiceModules(Class<? extends Module> cls) {
+    List<Module> result = m_guiceModules.get(cls);
+    return result;
+  }
+
+  @Override
+  public void addGuiceModule(Class<? extends Module> cls, Module module) {
+    List<Module> l = m_guiceModules.get(cls);
+    if (l == null) {
+      l = Lists.newArrayList();
+      m_guiceModules.put(cls,  l);
+    }
+    l.add(module);
+  }
+
+  private Map<List<Module>, Injector> m_injectors = Maps.newHashMap();
+
+  @Override
+  public Injector getInjector(List<Module> moduleInstances) {
+    return m_injectors .get(moduleInstances);
+  }
+
+  @Override
+  public void addInjector(List<Module> moduleInstances, Injector injector) {
+    m_injectors.put(moduleInstances, injector);
+  }
+
 } // TestRunner
diff --git a/src/main/java/org/testng/internal/ClassImpl.java b/src/main/java/org/testng/internal/ClassImpl.java
index dda4d58..785770c 100755
--- a/src/main/java/org/testng/internal/ClassImpl.java
+++ b/src/main/java/org/testng/internal/ClassImpl.java
@@ -1,5 +1,6 @@
 package org.testng.internal;
 
+import com.google.inject.Injector;
 import com.google.inject.Module;
 
 import org.testng.IClass;
@@ -136,14 +137,27 @@
       moduleInstances.add(module);
     }
 
-    return com.google.inject.Guice.createInjector(moduleInstances).getInstance(m_class);
+    // Reuse the previous injector, if any
+    Injector injector = m_testContext.getInjector(moduleInstances);
+    if (injector == null) {
+      injector = com.google.inject.Guice.createInjector(moduleInstances);
+      m_testContext.addInjector(moduleInstances, injector);
+    }
+    return injector.getInstance(m_class);
   }
 
   private Module[] getModules(Guice guice, Class<?> testClass) {
     List<Module> result = Lists.newArrayList();
     for (Class<? extends Module> moduleClass : guice.modules()) {
       try {
-        result.add(moduleClass.newInstance());
+        List<Module> modules = m_testContext.getGuiceModules(moduleClass);
+        if (modules != null && modules.size() > 0) {
+          result.addAll(modules);
+        } else {
+          Module instance = moduleClass.newInstance();
+          result.add(instance);
+          m_testContext.addGuiceModule(moduleClass, instance);
+        }
       } catch (InstantiationException e) {
         throw new TestNGException(e);
       } catch (IllegalAccessException e) {
diff --git a/src/test/java/test/guice/Guice1Test.java b/src/test/java/test/guice/Guice1Test.java
new file mode 100644
index 0000000..d4e413e
--- /dev/null
+++ b/src/test/java/test/guice/Guice1Test.java
@@ -0,0 +1,23 @@
+package test.guice;
+
+import com.google.inject.Inject;
+
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+
+import test.SimpleBaseTest;
+
+@Guice(modules = GuiceExampleModule.class)
+public class Guice1Test extends SimpleBaseTest {
+  static ISingleton m_object;
+
+  @Inject
+  ISingleton m_singleton;
+
+  @Test
+  public void singletonShouldWork() {
+    m_singleton.doSomething();
+    m_object = m_singleton;
+  }
+
+}
diff --git a/src/test/java/test/guice/Guice2Test.java b/src/test/java/test/guice/Guice2Test.java
new file mode 100644
index 0000000..ebe15f8
--- /dev/null
+++ b/src/test/java/test/guice/Guice2Test.java
@@ -0,0 +1,22 @@
+package test.guice;
+
+import com.google.inject.Inject;
+
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+
+import test.SimpleBaseTest;
+
+@Guice(modules = GuiceExampleModule.class)
+public class Guice2Test extends SimpleBaseTest {
+  static ISingleton m_object;
+
+  @Inject
+  ISingleton m_singleton;
+
+  @Test
+  public void singletonShouldWork() {
+    m_object = m_singleton;
+  }
+
+}
diff --git a/src/test/java/test/guice/GuiceTest.java b/src/test/java/test/guice/GuiceTest.java
index 4214072..452ef42 100644
--- a/src/test/java/test/guice/GuiceTest.java
+++ b/src/test/java/test/guice/GuiceTest.java
@@ -1,21 +1,23 @@
 package test.guice;
 
-import com.google.inject.Inject;
-
-import org.testng.annotations.Guice;
+import org.testng.TestNG;
 import org.testng.annotations.Test;
 
+import junit.framework.Assert;
+
 import test.SimpleBaseTest;
 
-@Guice(modules = GuiceExampleModule.class)
 public class GuiceTest extends SimpleBaseTest {
 
-  @Inject
-  ISingleton m_singleton;
-
   @Test
-  public void singletonShouldWork() {
-    m_singleton.doSomething();
-  }
+  public void guiceTest() {
+    TestNG tng = create(new Class[] { Guice1Test.class, Guice2Test.class});
+    Guice1Test.m_object = null;
+    Guice2Test.m_object = null;
+    tng.run();
 
+    Assert.assertNotNull(Guice1Test.m_object);
+    Assert.assertNotNull(Guice2Test.m_object);
+    Assert.assertEquals(Guice1Test.m_object, Guice2Test.m_object);
+  }
 }