don't reinstall modules that are equal

git-svn-id: https://google-guice.googlecode.com/svn/trunk@320 d779f126-a31b-0410-b53b-1d3aecad763e
diff --git a/src/com/google/inject/BinderImpl.java b/src/com/google/inject/BinderImpl.java
index 2d5f6c9..16e7883 100644
--- a/src/com/google/inject/BinderImpl.java
+++ b/src/com/google/inject/BinderImpl.java
@@ -65,6 +65,8 @@
   final List<StaticInjection> staticInjections
       = new ArrayList<StaticInjection>();
 
+  final Set<Module> modulesInstalled = new HashSet<Module>();
+
   InjectorImpl injector;
 
   final Stage stage;
@@ -194,7 +196,9 @@
   }
 
   public void install(Module module) {
-    module.configure(this);
+    if (modulesInstalled.add(module)) {
+      module.configure(this);
+    }
   }
 
   public void addError(String message, Object... arguments) {
diff --git a/test/com/google/inject/AllTests.java b/test/com/google/inject/AllTests.java
index 5fa642e..a1adb86 100644
--- a/test/com/google/inject/AllTests.java
+++ b/test/com/google/inject/AllTests.java
@@ -39,6 +39,7 @@
     suite.addTestSuite(GenericInjectionTest.class);
     suite.addTestSuite(ImplicitBindingTest.class);
     suite.addTestSuite(KeyTest.class);
+    suite.addTestSuite(ModuleTest.class);
     suite.addTestSuite(ProviderInjectionTest.class);
     suite.addTestSuite(NotRequiredTest.class);
     suite.addTestSuite(PreloadingTest.class);
diff --git a/test/com/google/inject/ModuleTest.java b/test/com/google/inject/ModuleTest.java
new file mode 100644
index 0000000..e938da5
--- /dev/null
+++ b/test/com/google/inject/ModuleTest.java
@@ -0,0 +1,56 @@
+// Copyright 2007 Google Inc. All Rights Reserved.
+
+package com.google.inject;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests relating to modules.
+ *
+ * @author kevinb
+ */
+public class ModuleTest extends TestCase {
+
+  static class A implements Module {
+    public void configure(Binder binder) {
+      binder.bind(X.class);
+      binder.install(new B());
+      binder.install(new C());
+    }
+  }
+
+  static class B implements Module {
+    public void configure(Binder binder) {
+      binder.bind(Y.class);
+      binder.install(new D());
+    }
+  }
+
+  static class C implements Module {
+    public void configure(Binder binder) {
+      binder.bind(Z.class);
+      binder.install(new D());
+    }
+  }
+
+  static class D implements Module {
+    public void configure(Binder binder) {
+      binder.bind(W.class);
+    }
+    @Override public boolean equals(Object obj) {
+      return obj.getClass() == D.class; // we're all equal in the eyes of guice
+    }
+    @Override public int hashCode() {
+      return D.class.hashCode();
+    }
+  }
+
+  static class X {}
+  static class Y {}
+  static class Z {}
+  static class W {}
+
+  public void testDiamond() throws Exception {
+    Guice.createInjector(new A());
+  }
+}