This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit be9711eba7040e848304f55d5ec03dfbf9d77a40
Author: Benoit Tellier <[email protected]>
AuthorDate: Tue Oct 29 13:07:56 2019 +0700

    JAMES-2938 Rely more on InitilizationOperationBuilder
---
 metrics/metrics-dropwizard/pom.xml                 |  4 +
 .../metrics/dropwizard/DropWizardJVMMetrics.java   |  4 +-
 .../dropwizard/DropWizardMetricFactory.java        |  3 +-
 .../modules/data/CassandraDomainListModule.java    | 30 ++------
 .../data/CassandraRecipientRewriteTableModule.java | 33 ++------
 .../data/CassandraUsersRepositoryModule.java       | 34 ++------
 .../mailbox/ElasticSearchMailboxModule.java        | 32 +++-----
 .../mailbox/ElasticSearchQuotaSearcherModule.java  | 32 +++-----
 .../modules/metrics/CassandraMetricsModule.java    | 38 +++------
 .../james/data/LdapUsersRepositoryModule.java      | 37 +++------
 .../modules/event/RabbitMQEventBusModule.java      | 29 ++-----
 .../server/ElasticSearchMetricReporterModule.java  | 34 ++------
 .../james/modules/server/DNSServiceModule.java     | 38 +++------
 .../modules/server/DropWizardMetricsModule.java    | 39 ++++------
 .../modules/server/MailStoreRepositoryModule.java  | 30 ++------
 .../james/modules/server/JMXServerModule.java      | 82 ++++++--------------
 .../james/modules/data/JPADomainListModule.java    | 32 ++------
 .../data/JPARecipientRewriteTableModule.java       | 34 ++------
 .../modules/data/JPAUsersRepositoryModule.java     | 34 ++------
 .../james/modules/mailbox/DefaultEventModule.java  | 32 ++------
 .../modules/server/CamelMailetContainerModule.java | 90 ++++++++--------------
 .../james/modules/data/MemoryDataModule.java       | 59 +++-----------
 .../james/modules/protocols/IMAPServerModule.java  | 35 +++------
 .../modules/protocols/JMAPDraftServerModule.java   | 49 ++++--------
 .../james/modules/protocols/LMTPServerModule.java  | 38 +++------
 .../modules/protocols/ManageSieveServerModule.java | 35 +++------
 .../james/modules/protocols/POP3ServerModule.java  | 37 +++------
 .../james/modules/protocols/SMTPServerModule.java  | 39 +++-------
 .../james/modules/server/WebAdminServerModule.java | 29 ++-----
 29 files changed, 282 insertions(+), 760 deletions(-)

diff --git a/metrics/metrics-dropwizard/pom.xml 
b/metrics/metrics-dropwizard/pom.xml
index 20e2423..9670a16 100644
--- a/metrics/metrics-dropwizard/pom.xml
+++ b/metrics/metrics-dropwizard/pom.xml
@@ -36,6 +36,10 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>james-server-lifecycle-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>testing-base</artifactId>
             <scope>test</scope>
         </dependency>
diff --git 
a/metrics/metrics-dropwizard/src/main/java/org/apache/james/metrics/dropwizard/DropWizardJVMMetrics.java
 
b/metrics/metrics-dropwizard/src/main/java/org/apache/james/metrics/dropwizard/DropWizardJVMMetrics.java
index 2312081..be5ea5b 100644
--- 
a/metrics/metrics-dropwizard/src/main/java/org/apache/james/metrics/dropwizard/DropWizardJVMMetrics.java
+++ 
b/metrics/metrics-dropwizard/src/main/java/org/apache/james/metrics/dropwizard/DropWizardJVMMetrics.java
@@ -21,6 +21,8 @@ package org.apache.james.metrics.dropwizard;
 
 import javax.inject.Inject;
 
+import org.apache.james.lifecycle.api.Startable;
+
 import com.codahale.metrics.MetricRegistry;
 import com.codahale.metrics.jvm.ClassLoadingGaugeSet;
 import com.codahale.metrics.jvm.FileDescriptorRatioGauge;
@@ -28,7 +30,7 @@ import com.codahale.metrics.jvm.GarbageCollectorMetricSet;
 import com.codahale.metrics.jvm.MemoryUsageGaugeSet;
 import com.codahale.metrics.jvm.ThreadStatesGaugeSet;
 
-public class DropWizardJVMMetrics {
+public class DropWizardJVMMetrics implements Startable {
 
     private final MetricRegistry metricRegistry;
 
diff --git 
a/metrics/metrics-dropwizard/src/main/java/org/apache/james/metrics/dropwizard/DropWizardMetricFactory.java
 
b/metrics/metrics-dropwizard/src/main/java/org/apache/james/metrics/dropwizard/DropWizardMetricFactory.java
index 03a9591..015c21d 100644
--- 
a/metrics/metrics-dropwizard/src/main/java/org/apache/james/metrics/dropwizard/DropWizardMetricFactory.java
+++ 
b/metrics/metrics-dropwizard/src/main/java/org/apache/james/metrics/dropwizard/DropWizardMetricFactory.java
@@ -23,6 +23,7 @@ import javax.annotation.PostConstruct;
 import javax.annotation.PreDestroy;
 import javax.inject.Inject;
 
+import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.metrics.api.Metric;
 import org.apache.james.metrics.api.MetricFactory;
 import org.apache.james.metrics.api.TimeMetric;
@@ -30,7 +31,7 @@ import org.apache.james.metrics.api.TimeMetric;
 import com.codahale.metrics.MetricRegistry;
 import com.codahale.metrics.jmx.JmxReporter;
 
-public class DropWizardMetricFactory implements MetricFactory {
+public class DropWizardMetricFactory implements MetricFactory, Startable {
 
     private final MetricRegistry metricRegistry;
     private final JmxReporter jmxReporter;
diff --git 
a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraDomainListModule.java
 
b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraDomainListModule.java
index 82ad33f..578d745 100644
--- 
a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraDomainListModule.java
+++ 
b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraDomainListModule.java
@@ -23,16 +23,16 @@ import 
org.apache.james.backends.cassandra.components.CassandraModule;
 import org.apache.james.domainlist.api.DomainList;
 import org.apache.james.domainlist.cassandra.CassandraDomainList;
 import org.apache.james.domainlist.lib.DomainListConfiguration;
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Provides;
 import com.google.inject.Scopes;
 import com.google.inject.Singleton;
 import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class CassandraDomainListModule extends AbstractModule {
 
@@ -41,7 +41,6 @@ public class CassandraDomainListModule extends AbstractModule 
{
         bind(CassandraDomainList.class).in(Scopes.SINGLETON);
         bind(DomainList.class).to(CassandraDomainList.class);
         Multibinder.newSetBinder(binder(), 
CassandraModule.class).addBinding().toInstance(org.apache.james.domainlist.cassandra.CassandraDomainListModule.MODULE);
-        Multibinder.newSetBinder(binder(), 
InitializationOperation.class).addBinding().to(CassandraDomainListInitializationOperation.class);
     }
 
     @Provides
@@ -53,26 +52,11 @@ public class CassandraDomainListModule extends 
AbstractModule {
             throw new RuntimeException(e);
         }
     }
-    
-    @Singleton
-    public static class CassandraDomainListInitializationOperation implements 
InitializationOperation {
-        private final DomainListConfiguration configuration;
-        private final CassandraDomainList cassandraDomainList;
-
-        @Inject
-        public 
CassandraDomainListInitializationOperation(DomainListConfiguration 
configuration, CassandraDomainList cassandraDomainList) {
-            this.configuration = configuration;
-            this.cassandraDomainList = cassandraDomainList;
-        }
 
-        @Override
-        public void initModule() throws Exception {
-            cassandraDomainList.configure(configuration);
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return CassandraDomainList.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation configureDomainList(DomainListConfiguration 
configuration, CassandraDomainList cassandraDomainList) {
+        return InitilizationOperationBuilder
+            .forClass(CassandraDomainList.class)
+            .init(() -> cassandraDomainList.configure(configuration));
     }
 }
diff --git 
a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraRecipientRewriteTableModule.java
 
b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraRecipientRewriteTableModule.java
index c20887e..939f641 100644
--- 
a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraRecipientRewriteTableModule.java
+++ 
b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraRecipientRewriteTableModule.java
@@ -19,7 +19,6 @@
 package org.apache.james.modules.data;
 
 import org.apache.james.backends.cassandra.components.CassandraModule;
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.rrt.api.RecipientRewriteTable;
 import org.apache.james.rrt.cassandra.CassandraMappingsSourcesDAO;
 import org.apache.james.rrt.cassandra.CassandraRRTModule;
@@ -27,15 +26,14 @@ import 
org.apache.james.rrt.cassandra.CassandraRecipientRewriteTable;
 import org.apache.james.rrt.cassandra.CassandraRecipientRewriteTableDAO;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Scopes;
-import com.google.inject.Singleton;
 import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class CassandraRecipientRewriteTableModule extends AbstractModule {
-
     @Override
     public void configure() {
         bind(CassandraRecipientRewriteTable.class).in(Scopes.SINGLETON);
@@ -44,29 +42,12 @@ public class CassandraRecipientRewriteTableModule extends 
AbstractModule {
         
bind(RecipientRewriteTable.class).to(CassandraRecipientRewriteTable.class);
         Multibinder<CassandraModule> cassandraDataDefinitions = 
Multibinder.newSetBinder(binder(), CassandraModule.class);
         
cassandraDataDefinitions.addBinding().toInstance(CassandraRRTModule.MODULE);
-        Multibinder.newSetBinder(binder(), 
InitializationOperation.class).addBinding().to(CassandraRecipientRewriteTablePerformer.class);
     }
 
-    @Singleton
-    public static class CassandraRecipientRewriteTablePerformer implements 
InitializationOperation {
-        private final ConfigurationProvider configurationProvider;
-        private final CassandraRecipientRewriteTable recipientRewriteTable;
-
-        @Inject
-        public CassandraRecipientRewriteTablePerformer(ConfigurationProvider 
configurationProvider, CassandraRecipientRewriteTable recipientRewriteTable) {
-            this.configurationProvider = configurationProvider;
-            this.recipientRewriteTable = recipientRewriteTable;
-        }
-
-        @Override
-        public void initModule() throws Exception {
-            
recipientRewriteTable.configure(configurationProvider.getConfiguration("recipientrewritetable"));
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return CassandraRecipientRewriteTable.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation 
configureRecipientRewriteTable(ConfigurationProvider configurationProvider, 
CassandraRecipientRewriteTable recipientRewriteTable) {
+        return InitilizationOperationBuilder
+            .forClass(CassandraRecipientRewriteTable.class)
+            .init(() -> 
recipientRewriteTable.configure(configurationProvider.getConfiguration("recipientrewritetable")));
     }
-
 }
diff --git 
a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraUsersRepositoryModule.java
 
b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraUsersRepositoryModule.java
index 457af24..5f38aa5 100644
--- 
a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraUsersRepositoryModule.java
+++ 
b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraUsersRepositoryModule.java
@@ -19,17 +19,16 @@
 package org.apache.james.modules.data;
 
 import org.apache.james.backends.cassandra.components.CassandraModule;
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.cassandra.CassandraUsersRepository;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Scopes;
-import com.google.inject.Singleton;
 import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class CassandraUsersRepositoryModule extends AbstractModule {
     @Override
@@ -38,31 +37,12 @@ public class CassandraUsersRepositoryModule extends 
AbstractModule {
         bind(UsersRepository.class).to(CassandraUsersRepository.class);
         Multibinder<CassandraModule> cassandraDataDefinitions = 
Multibinder.newSetBinder(binder(), CassandraModule.class);
         
cassandraDataDefinitions.addBinding().toInstance(org.apache.james.user.cassandra.CassandraUsersRepositoryModule.MODULE);
-
-        Multibinder.newSetBinder(binder(), 
InitializationOperation.class).addBinding().to(CassandraUsersRepositoryInitializationOperation.class);
     }
 
-    @Singleton
-    public static class CassandraUsersRepositoryInitializationOperation 
implements InitializationOperation {
-
-        private final ConfigurationProvider configurationProvider;
-        private final CassandraUsersRepository usersRepository;
-
-        @Inject
-        public 
CassandraUsersRepositoryInitializationOperation(ConfigurationProvider 
configurationProvider, CassandraUsersRepository usersRepository) {
-            this.configurationProvider = configurationProvider;
-            this.usersRepository = usersRepository;
-        }
-
-        @Override
-        public void initModule() throws Exception {
-            
usersRepository.configure(configurationProvider.getConfiguration("usersrepository"));
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return CassandraUsersRepository.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation configureUsersRepository(ConfigurationProvider 
configurationProvider, CassandraUsersRepository usersRepository) {
+        return InitilizationOperationBuilder
+            .forClass(CassandraUsersRepository.class)
+            .init(() -> 
usersRepository.configure(configurationProvider.getConfiguration("usersrepository")));
     }
-
 }
diff --git 
a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/ElasticSearchMailboxModule.java
 
b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/ElasticSearchMailboxModule.java
index f7e12f2..6bd4f54 100644
--- 
a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/ElasticSearchMailboxModule.java
+++ 
b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/ElasticSearchMailboxModule.java
@@ -47,6 +47,7 @@ import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.store.search.ListeningMessageSearchIndex;
 import org.apache.james.mailbox.store.search.MessageSearchIndex;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 import org.apache.james.utils.PropertiesProvider;
 import org.elasticsearch.client.RestHighLevelClient;
 import org.slf4j.Logger;
@@ -56,6 +57,7 @@ import com.google.inject.AbstractModule;
 import com.google.inject.Provides;
 import com.google.inject.Scopes;
 import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class ElasticSearchMailboxModule extends AbstractModule {
 
@@ -83,25 +85,6 @@ public class ElasticSearchMailboxModule extends 
AbstractModule {
         }
     }
 
-    static class ElasticSearchMailboxIndexCreationPerformer implements 
InitializationOperation {
-        private final MailboxIndexCreator mailboxIndexCreator;
-
-        @Inject
-        ElasticSearchMailboxIndexCreationPerformer(MailboxIndexCreator 
mailboxIndexCreator) {
-            this.mailboxIndexCreator = mailboxIndexCreator;
-        }
-
-        @Override
-        public void initModule()  throws Exception {
-            mailboxIndexCreator.createIndex();
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return MailboxIndexCreator.class;
-        }
-    }
-
     private static final Logger LOGGER = 
LoggerFactory.getLogger(ElasticSearchMailboxModule.class);
 
     public static final String ELASTICSEARCH_CONFIGURATION_NAME = 
"elasticsearch";
@@ -118,10 +101,6 @@ public class ElasticSearchMailboxModule extends 
AbstractModule {
             .addBinding()
             .to(ElasticSearchListeningMessageSearchIndex.class);
 
-        Multibinder.newSetBinder(binder(), InitializationOperation.class)
-            .addBinding()
-            .to(ElasticSearchMailboxIndexCreationPerformer.class);
-
         Multibinder.newSetBinder(binder(), StartUpCheck.class)
             .addBinding()
             .to(ElasticSearchStartUpCheck.class);
@@ -184,4 +163,11 @@ public class ElasticSearchMailboxModule extends 
AbstractModule {
         return configuration.getIndexAttachment();
     }
 
+    @ProvidesIntoSet
+    InitializationOperation createIndex(MailboxIndexCreator instance) {
+        return InitilizationOperationBuilder
+            .forClass(MailboxIndexCreator.class)
+            .init(instance::createIndex);
+    }
+
 }
diff --git 
a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/ElasticSearchQuotaSearcherModule.java
 
b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/ElasticSearchQuotaSearcherModule.java
index 93eb8f1..fc98f6e 100644
--- 
a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/ElasticSearchQuotaSearcherModule.java
+++ 
b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/mailbox/ElasticSearchQuotaSearcherModule.java
@@ -39,6 +39,7 @@ import 
org.apache.james.quota.search.elasticsearch.QuotaSearchIndexCreationUtil;
 import 
org.apache.james.quota.search.elasticsearch.events.ElasticSearchQuotaMailboxListener;
 import 
org.apache.james.quota.search.elasticsearch.json.QuotaRatioToElasticSearchJson;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 import org.apache.james.utils.PropertiesProvider;
 import org.elasticsearch.client.RestHighLevelClient;
 import org.slf4j.Logger;
@@ -48,6 +49,7 @@ import com.google.inject.AbstractModule;
 import com.google.inject.Provides;
 import com.google.inject.Singleton;
 import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class ElasticSearchQuotaSearcherModule extends AbstractModule {
 
@@ -74,25 +76,6 @@ public class ElasticSearchQuotaSearcherModule extends 
AbstractModule {
         }
     }
 
-    static class ElasticSearchQuotaIndexCreationPerformer implements 
InitializationOperation {
-        private final ElasticSearchQuotaIndexCreator indexCreator;
-
-        @Inject
-        
ElasticSearchQuotaIndexCreationPerformer(ElasticSearchQuotaIndexCreator 
indexCreator) {
-            this.indexCreator = indexCreator;
-        }
-
-        @Override
-        public void initModule() throws Exception {
-            indexCreator.createIndex();
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return ElasticSearchQuotaIndexCreator.class;
-        }
-    }
-
     private static final Logger LOGGER = 
LoggerFactory.getLogger(ElasticSearchQuotaSearcherModule.class);
 
     @Override
@@ -100,10 +83,6 @@ public class ElasticSearchQuotaSearcherModule extends 
AbstractModule {
         Multibinder.newSetBinder(binder(), 
MailboxListener.GroupMailboxListener.class)
             .addBinding()
             .to(ElasticSearchQuotaMailboxListener.class);
-
-        Multibinder.newSetBinder(binder(), InitializationOperation.class)
-            .addBinding()
-            .to(ElasticSearchQuotaIndexCreationPerformer.class);
     }
 
     @Provides
@@ -134,4 +113,11 @@ public class ElasticSearchQuotaSearcherModule extends 
AbstractModule {
                 configuration.getWriteAliasQuotaRatioName()),
                 new QuotaRatioToElasticSearchJson());
     }
+
+    @ProvidesIntoSet
+    InitializationOperation createIndex(ElasticSearchQuotaIndexCreator 
instance) {
+        return InitilizationOperationBuilder
+            .forClass(ElasticSearchQuotaIndexCreator.class)
+            .init(instance::createIndex);
+    }
 }
diff --git 
a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/metrics/CassandraMetricsModule.java
 
b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/metrics/CassandraMetricsModule.java
index 9491b24..f8a3520 100644
--- 
a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/metrics/CassandraMetricsModule.java
+++ 
b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/metrics/CassandraMetricsModule.java
@@ -21,48 +21,32 @@ package org.apache.james.modules.metrics;
 
 import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 
 import com.codahale.metrics.MetricRegistry;
 import com.datastax.driver.core.Session;
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Scopes;
-import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class CassandraMetricsModule extends AbstractModule {
-
     @Override
     protected void configure() {
         bind(CassandraMetricsInjector.class)
             .in(Scopes.SINGLETON);
-
-        Multibinder.newSetBinder(binder(), InitializationOperation.class)
-            .addBinding()
-            .to(CassandraMetricsInjector.class);
     }
 
-    public static class CassandraMetricsInjector implements 
InitializationOperation, Startable {
-
-        private final MetricRegistry metricRegistry;
-        private final Session session;
-
-        @Inject
-        public CassandraMetricsInjector(MetricRegistry metricRegistry, Session 
session) {
-            this.metricRegistry = metricRegistry;
-            this.session = session;
-        }
-
-        @Override
-        public void initModule() {
-            metricRegistry.registerAll(
+    @ProvidesIntoSet
+    InitializationOperation injectMetrics(MetricRegistry metricRegistry, 
Session session) {
+        return InitilizationOperationBuilder
+            .forClass(CassandraMetricsInjector.class)
+            .init(() -> metricRegistry.registerAll(
                 session.getCluster()
                     .getMetrics()
-                    .getRegistry());
-        }
+                    .getRegistry()));
+    }
+
+    public static class CassandraMetricsInjector implements Startable {
 
-        @Override
-        public Class<? extends Startable> forClass() {
-            return CassandraMetricsInjector.class;
-        }
     }
 }
diff --git 
a/server/container/guice/cassandra-ldap-guice/src/main/java/org/apache/james/data/LdapUsersRepositoryModule.java
 
b/server/container/guice/cassandra-ldap-guice/src/main/java/org/apache/james/data/LdapUsersRepositoryModule.java
index 0b058ae..bdee231 100644
--- 
a/server/container/guice/cassandra-ldap-guice/src/main/java/org/apache/james/data/LdapUsersRepositoryModule.java
+++ 
b/server/container/guice/cassandra-ldap-guice/src/main/java/org/apache/james/data/LdapUsersRepositoryModule.java
@@ -19,28 +19,24 @@
 package org.apache.james.data;
 
 import org.apache.commons.configuration2.ex.ConfigurationException;
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.ldap.LdapRepositoryConfiguration;
 import org.apache.james.user.ldap.ReadOnlyUsersLDAPRepository;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Provides;
 import com.google.inject.Scopes;
 import com.google.inject.Singleton;
-import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class LdapUsersRepositoryModule extends AbstractModule {
-
     @Override
     public void configure() {
         bind(ReadOnlyUsersLDAPRepository.class).in(Scopes.SINGLETON);
         bind(UsersRepository.class).to(ReadOnlyUsersLDAPRepository.class);
-
-        Multibinder.newSetBinder(binder(), 
InitializationOperation.class).addBinding().to(LdapUsersRepositoryInitializationOperation.class);
     }
 
     @Provides
@@ -50,26 +46,13 @@ public class LdapUsersRepositoryModule extends 
AbstractModule {
             configurationProvider.getConfiguration("usersrepository"));
     }
 
-    @Singleton
-    public static class LdapUsersRepositoryInitializationOperation implements 
InitializationOperation {
-        private final LdapRepositoryConfiguration configuration;
-        private final ReadOnlyUsersLDAPRepository usersRepository;
-
-        @Inject
-        public 
LdapUsersRepositoryInitializationOperation(LdapRepositoryConfiguration 
configuration, ReadOnlyUsersLDAPRepository usersRepository) {
-            this.configuration = configuration;
-            this.usersRepository = usersRepository;
-        }
-
-        @Override
-        public void initModule() throws Exception {
-            usersRepository.configure(configuration);
-            usersRepository.init();
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return ReadOnlyUsersLDAPRepository.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation configureLdap(LdapRepositoryConfiguration 
configuration, ReadOnlyUsersLDAPRepository usersRepository) {
+        return InitilizationOperationBuilder
+            .forClass(ReadOnlyUsersLDAPRepository.class)
+            .init(() -> {
+                usersRepository.configure(configuration);
+                usersRepository.init();
+            });
     }
 }
diff --git 
a/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/event/RabbitMQEventBusModule.java
 
b/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/event/RabbitMQEventBusModule.java
index 41e8fc9..038afb6 100644
--- 
a/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/event/RabbitMQEventBusModule.java
+++ 
b/server/container/guice/cassandra-rabbitmq-guice/src/main/java/org/apache/james/modules/event/RabbitMQEventBusModule.java
@@ -20,18 +20,18 @@
 package org.apache.james.modules.event;
 
 import org.apache.james.event.json.EventSerializer;
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.events.MailboxIdRegistrationKey;
 import org.apache.james.mailbox.events.RabbitMQEventBus;
 import org.apache.james.mailbox.events.RegistrationKey;
 import org.apache.james.mailbox.events.RetryBackoffConfiguration;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Scopes;
 import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class RabbitMQEventBusModule extends AbstractModule {
 
@@ -45,28 +45,13 @@ public class RabbitMQEventBusModule extends AbstractModule {
         Multibinder.newSetBinder(binder(), RegistrationKey.Factory.class)
             .addBinding().to(MailboxIdRegistrationKey.Factory.class);
 
-        Multibinder.newSetBinder(binder(), InitializationOperation.class)
-            .addBinding().to(RabbitMQEventBusInitializer.class);
-
         
bind(RetryBackoffConfiguration.class).toInstance(RetryBackoffConfiguration.DEFAULT);
     }
 
-    static class RabbitMQEventBusInitializer implements 
InitializationOperation {
-        private final RabbitMQEventBus rabbitMQEventBus;
-
-        @Inject
-        RabbitMQEventBusInitializer(RabbitMQEventBus rabbitMQEventBus) {
-            this.rabbitMQEventBus = rabbitMQEventBus;
-        }
-
-        @Override
-        public void initModule() {
-            rabbitMQEventBus.start();
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return RabbitMQEventBus.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation workQueue(RabbitMQEventBus instance) {
+        return InitilizationOperationBuilder
+            .forClass(RabbitMQEventBus.class)
+            .init(instance::start);
     }
 }
diff --git 
a/server/container/guice/es-metric-reporter/src/main/java/org/apache/james/modules/server/ElasticSearchMetricReporterModule.java
 
b/server/container/guice/es-metric-reporter/src/main/java/org/apache/james/modules/server/ElasticSearchMetricReporterModule.java
index d0bf64b..f38f0ef 100644
--- 
a/server/container/guice/es-metric-reporter/src/main/java/org/apache/james/modules/server/ElasticSearchMetricReporterModule.java
+++ 
b/server/container/guice/es-metric-reporter/src/main/java/org/apache/james/modules/server/ElasticSearchMetricReporterModule.java
@@ -23,19 +23,18 @@ import java.io.FileNotFoundException;
 
 import org.apache.commons.configuration2.Configuration;
 import org.apache.commons.configuration2.ex.ConfigurationException;
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.metrics.es.ESMetricReporter;
 import org.apache.james.metrics.es.ESReporterConfiguration;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 import org.apache.james.utils.PropertiesProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Provides;
 import com.google.inject.Singleton;
-import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class ElasticSearchMetricReporterModule extends AbstractModule {
     private static final String ELASTICSEARCH_CONFIGURATION_NAME = 
"elasticsearch";
@@ -46,11 +45,6 @@ public class ElasticSearchMetricReporterModule extends 
AbstractModule {
     public static final boolean DEFAULT_DISABLE = false;
     public static final int DEFAULT_ES_HTTP_PORT = 9200;
 
-    @Override
-    protected void configure() {
-        Multibinder.newSetBinder(binder(), 
InitializationOperation.class).addBinding().to(ESMetricReporterStarter.class);
-    }
-
     @Provides
     @Singleton
     public ESReporterConfiguration provideConfiguration(PropertiesProvider 
propertiesProvider) throws ConfigurationException {
@@ -83,24 +77,10 @@ public class ElasticSearchMetricReporterModule extends 
AbstractModule {
         return 
propertiesReader.getBoolean("elasticsearch.metrics.reports.enabled", 
DEFAULT_DISABLE);
     }
 
-    @Singleton
-    public static class ESMetricReporterStarter implements 
InitializationOperation {
-        private final ESMetricReporter esMetricReporter;
-
-        @Inject
-        public ESMetricReporterStarter(ESMetricReporter esMetricReporter) {
-            this.esMetricReporter = esMetricReporter;
-        }
-
-        @Override
-        public void initModule() {
-            esMetricReporter.start();
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return ESMetricReporter.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation startReporter(ESMetricReporter instance) {
+        return InitilizationOperationBuilder
+            .forClass(ESMetricReporter.class)
+            .init(instance::start);
     }
-
 }
diff --git 
a/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/DNSServiceModule.java
 
b/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/DNSServiceModule.java
index 3736d6a..60bb81e 100644
--- 
a/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/DNSServiceModule.java
+++ 
b/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/DNSServiceModule.java
@@ -20,46 +20,28 @@ package org.apache.james.modules.server;
 
 import org.apache.james.dnsservice.api.DNSService;
 import org.apache.james.dnsservice.dnsjava.DNSJavaService;
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Scopes;
-import com.google.inject.Singleton;
-import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class DNSServiceModule extends AbstractModule {
-
     @Override
     protected void configure() {
         bind(DNSJavaService.class).in(Scopes.SINGLETON);
         bind(DNSService.class).to(DNSJavaService.class);
-        Multibinder.newSetBinder(binder(), 
InitializationOperation.class).addBinding().to(DNSServiceInitializationOperation.class);
     }
 
-    @Singleton
-    public static class DNSServiceInitializationOperation implements 
InitializationOperation {
-        private final ConfigurationProvider configurationProvider;
-        private final DNSJavaService dnsService;
-
-        @Inject
-        public DNSServiceInitializationOperation(ConfigurationProvider 
configurationProvider,
-                                                 DNSJavaService dnsService) {
-            this.configurationProvider = configurationProvider;
-            this.dnsService = dnsService;
-        }
-
-        @Override
-        public void initModule()  throws Exception {
-            
dnsService.configure(configurationProvider.getConfiguration("dnsservice"));
-            dnsService.init();
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return DNSJavaService.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation configureDNS(ConfigurationProvider 
configurationProvider, DNSJavaService dnsService) {
+        return InitilizationOperationBuilder
+            .forClass(DNSJavaService.class)
+            .init(() -> {
+                
dnsService.configure(configurationProvider.getConfiguration("dnsservice"));
+                dnsService.init();
+            });
     }
 }
\ No newline at end of file
diff --git 
a/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/DropWizardMetricsModule.java
 
b/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/DropWizardMetricsModule.java
index 8893fbe..fa542ea 100644
--- 
a/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/DropWizardMetricsModule.java
+++ 
b/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/DropWizardMetricsModule.java
@@ -19,20 +19,18 @@
 
 package org.apache.james.modules.server;
 
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.metrics.api.GaugeRegistry;
 import org.apache.james.metrics.api.MetricFactory;
 import org.apache.james.metrics.dropwizard.DropWizardGaugeRegistry;
 import org.apache.james.metrics.dropwizard.DropWizardJVMMetrics;
 import org.apache.james.metrics.dropwizard.DropWizardMetricFactory;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 
 import com.codahale.metrics.MetricRegistry;
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Scopes;
-import com.google.inject.Singleton;
-import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class DropWizardMetricsModule extends AbstractModule {
 
@@ -45,30 +43,19 @@ public class DropWizardMetricsModule extends AbstractModule 
{
         bind(MetricFactory.class).to(DropWizardMetricFactory.class);
 
         bind(GaugeRegistry.class).to(DropWizardGaugeRegistry.class);
-
-        Multibinder.newSetBinder(binder(), 
InitializationOperation.class).addBinding().to(DropWizardInitializationOperation.class);
     }
 
-    @Singleton
-    public static class DropWizardInitializationOperation implements 
InitializationOperation, Startable {
-        private final DropWizardMetricFactory dropWizardMetricFactory;
-        private final DropWizardJVMMetrics dropWizardJVMMetrics;
-
-        @Inject
-        public DropWizardInitializationOperation(DropWizardMetricFactory 
dropWizardMetricFactory, DropWizardJVMMetrics dropWizardJVMMetrics) {
-            this.dropWizardMetricFactory = dropWizardMetricFactory;
-            this.dropWizardJVMMetrics = dropWizardJVMMetrics;
-        }
-
-        @Override
-        public void initModule() {
-            dropWizardMetricFactory.start();
-            dropWizardJVMMetrics.start();
-        }
+    @ProvidesIntoSet
+    InitializationOperation startMetricFactory(DropWizardMetricFactory 
instance) {
+        return InitilizationOperationBuilder
+            .forClass(DropWizardMetricFactory.class)
+            .init(instance::start);
+    }
 
-        @Override
-        public Class<? extends Startable> forClass() {
-            return DropWizardInitializationOperation.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation startJVMMetrics(DropWizardJVMMetrics instance) {
+        return InitilizationOperationBuilder
+            .forClass(DropWizardJVMMetrics.class)
+            .init(instance::start);
     }
 }
diff --git 
a/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/MailStoreRepositoryModule.java
 
b/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/MailStoreRepositoryModule.java
index 6822d80..bf6eee1 100644
--- 
a/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/MailStoreRepositoryModule.java
+++ 
b/server/container/guice/guice-common/src/main/java/org/apache/james/modules/server/MailStoreRepositoryModule.java
@@ -24,7 +24,6 @@ import java.util.function.Supplier;
 import org.apache.commons.configuration2.HierarchicalConfiguration;
 import org.apache.commons.configuration2.ex.ConfigurationException;
 import org.apache.commons.configuration2.tree.ImmutableNode;
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.mailrepository.api.MailRepositoryStore;
 import org.apache.james.mailrepository.memory.MailRepositoryLoader;
 import org.apache.james.mailrepository.memory.MailRepositoryStoreConfiguration;
@@ -32,19 +31,19 @@ import 
org.apache.james.mailrepository.memory.MemoryMailRepositoryStore;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.utils.GuiceProbe;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 import org.apache.james.utils.MailRepositoryProbeImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Provides;
 import com.google.inject.Scopes;
 import com.google.inject.Singleton;
 import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class MailStoreRepositoryModule extends AbstractModule {
-
     public static final Logger LOGGER = 
LoggerFactory.getLogger(MailStoreRepositoryModule.class);
 
     public interface DefaultItemSupplier extends 
Supplier<MailRepositoryStoreConfiguration.Item> {}
@@ -57,7 +56,6 @@ public class MailStoreRepositoryModule extends AbstractModule 
{
         bind(GuiceMailRepositoryLoader.class).in(Scopes.SINGLETON);
         bind(MailRepositoryLoader.class).to(GuiceMailRepositoryLoader.class);
 
-        Multibinder.newSetBinder(binder(), 
InitializationOperation.class).addBinding().to(MailRepositoryStoreModuleInitializationOperation.class);
         Multibinder.newSetBinder(binder(), 
GuiceProbe.class).addBinding().to(MailRepositoryProbeImpl.class);
     }
 
@@ -73,24 +71,10 @@ public class MailStoreRepositoryModule extends 
AbstractModule {
         return 
MailRepositoryStoreConfiguration.forItems(defaultItemSupplier.get());
     }
 
-    @Singleton
-    public static class MailRepositoryStoreModuleInitializationOperation 
implements InitializationOperation {
-        private final MemoryMailRepositoryStore javaMailRepositoryStore;
-
-        @Inject
-        public 
MailRepositoryStoreModuleInitializationOperation(MemoryMailRepositoryStore 
javaMailRepositoryStore) {
-            this.javaMailRepositoryStore = javaMailRepositoryStore;
-        }
-
-        @Override
-        public void initModule() throws Exception {
-            javaMailRepositoryStore.init();
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return MemoryMailRepositoryStore.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation startMailStore(MemoryMailRepositoryStore instance) 
{
+        return InitilizationOperationBuilder
+            .forClass(MemoryMailRepositoryStore.class)
+            .init(instance::init);
     }
-
 }
diff --git 
a/server/container/guice/jmx/src/main/java/org/apache/james/modules/server/JMXServerModule.java
 
b/server/container/guice/jmx/src/main/java/org/apache/james/modules/server/JMXServerModule.java
index 0f0fdbe..36e6579 100644
--- 
a/server/container/guice/jmx/src/main/java/org/apache/james/modules/server/JMXServerModule.java
+++ 
b/server/container/guice/jmx/src/main/java/org/apache/james/modules/server/JMXServerModule.java
@@ -33,7 +33,6 @@ import org.apache.james.adapter.mailbox.ReIndexerManagement;
 import org.apache.james.adapter.mailbox.ReIndexerManagementMBean;
 import org.apache.james.domainlist.api.DomainListManagementMBean;
 import org.apache.james.domainlist.lib.DomainListManagement;
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.mailbox.copier.MailboxCopier;
 import org.apache.james.mailbox.indexer.ReIndexer;
 import org.apache.james.mailbox.tools.copier.MailboxCopierImpl;
@@ -47,17 +46,17 @@ import 
org.apache.james.user.api.UsersRepositoryManagementMBean;
 import org.apache.james.user.lib.UsersRepositoryManagement;
 import org.apache.james.utils.GuiceMailboxManagerResolver;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 import org.apache.james.utils.PropertiesProvider;
 import org.apache.mailbox.tools.indexer.ReIndexerImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Provides;
 import com.google.inject.Scopes;
 import com.google.inject.Singleton;
-import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 import com.google.inject.name.Names;
 
 public class JMXServerModule extends AbstractModule {
@@ -96,8 +95,6 @@ public class JMXServerModule extends AbstractModule {
         bind(ReIndexerManagementMBean.class).to(ReIndexerManagement.class);
         bind(QuotaManagementMBean.class).to(QuotaManagement.class);
         
bind(SieveRepositoryManagementMBean.class).to(SieveRepositoryManagement.class);
-        Multibinder<InitializationOperation> configurationMultibinder = 
Multibinder.newSetBinder(binder(), InitializationOperation.class);
-        
configurationMultibinder.addBinding().to(JMXModuleInitializationOperation.class);
     }
 
     @Provides
@@ -111,57 +108,28 @@ public class JMXServerModule extends AbstractModule {
         }
     }
 
-    @Singleton
-    public static class JMXModuleInitializationOperation implements 
InitializationOperation {
-
-        private final JMXServer jmxServer;
-        private final DomainListManagementMBean domainListManagementMBean;
-        private final UsersRepositoryManagementMBean 
usersRepositoryManagementMBean;
-        private final RecipientRewriteTableManagementMBean 
recipientRewriteTableManagementMBean;
-        private final MailboxManagerManagementMBean 
mailboxManagerManagementMBean;
-        private final MailboxCopierManagementMBean 
mailboxCopierManagementMBean;
-        private final ReIndexerManagementMBean reIndexerManagementMBean;
-        private final QuotaManagementMBean quotaManagementMBean;
-        private final SieveRepositoryManagementMBean 
sieveRepositoryManagementMBean;
-
-        @Inject
-        public JMXModuleInitializationOperation(JMXServer jmxServer,
-                                                DomainListManagementMBean 
domainListManagementMBean,
-                                                UsersRepositoryManagementMBean 
usersRepositoryManagementMBean,
-                                                
RecipientRewriteTableManagementMBean recipientRewriteTableManagementMBean,
-                                                MailboxManagerManagementMBean 
mailboxManagerManagementMBean,
-                                                MailboxCopierManagementMBean 
mailboxCopierManagementMBean,
-                                                ReIndexerManagementMBean 
reIndexerManagementMBean,
-                                                QuotaManagementMBean 
quotaManagementMBean,
-                                                SieveRepositoryManagementMBean 
sieveRepositoryManagementMBean) {
-            this.jmxServer = jmxServer;
-            this.domainListManagementMBean = domainListManagementMBean;
-            this.usersRepositoryManagementMBean = 
usersRepositoryManagementMBean;
-            this.recipientRewriteTableManagementMBean = 
recipientRewriteTableManagementMBean;
-            this.mailboxManagerManagementMBean = mailboxManagerManagementMBean;
-            this.mailboxCopierManagementMBean = mailboxCopierManagementMBean;
-            this.reIndexerManagementMBean = reIndexerManagementMBean;
-            this.quotaManagementMBean = quotaManagementMBean;
-            this.sieveRepositoryManagementMBean = 
sieveRepositoryManagementMBean;
-        }
-
-        @Override
-        public void initModule() throws Exception {
-            jmxServer.start();
-            jmxServer.register(JMX_COMPONENT_DOMAINLIST, 
domainListManagementMBean);
-            jmxServer.register(JMX_COMPONENT_USERS_REPOSITORY, 
usersRepositoryManagementMBean);
-            jmxServer.register(JMX_COMPONENT_RECIPIENTREWRITETABLE, 
recipientRewriteTableManagementMBean);
-            jmxServer.register(JMX_COMPONENT_NAME_MAILBOXMANAGERBEAN, 
mailboxManagerManagementMBean);
-            jmxServer.register(JMX_COMPONENT_MAILBOXCOPIER, 
mailboxCopierManagementMBean);
-            jmxServer.register(JMX_COMPONENT_REINDEXER, 
reIndexerManagementMBean);
-            jmxServer.register(JMX_COMPONENT_QUOTA, quotaManagementMBean);
-            jmxServer.register(JMX_COMPONENT_SIEVE, 
sieveRepositoryManagementMBean);
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return JMXServer.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation startJmxServer(JMXServer jmxServer,
+                                        DomainListManagementMBean 
domainListManagementMBean,
+                                        UsersRepositoryManagementMBean 
usersRepositoryManagementMBean,
+                                        RecipientRewriteTableManagementMBean 
recipientRewriteTableManagementMBean,
+                                        MailboxManagerManagementMBean 
mailboxManagerManagementMBean,
+                                        MailboxCopierManagementMBean 
mailboxCopierManagementMBean,
+                                        ReIndexerManagementMBean 
reIndexerManagementMBean,
+                                        QuotaManagementMBean 
quotaManagementMBean,
+                                        SieveRepositoryManagementMBean 
sieveRepositoryManagementMBean) {
+        return InitilizationOperationBuilder
+            .forClass(JMXServer.class)
+            .init(() -> {
+                jmxServer.start();
+                jmxServer.register(JMX_COMPONENT_DOMAINLIST, 
domainListManagementMBean);
+                jmxServer.register(JMX_COMPONENT_USERS_REPOSITORY, 
usersRepositoryManagementMBean);
+                jmxServer.register(JMX_COMPONENT_RECIPIENTREWRITETABLE, 
recipientRewriteTableManagementMBean);
+                jmxServer.register(JMX_COMPONENT_NAME_MAILBOXMANAGERBEAN, 
mailboxManagerManagementMBean);
+                jmxServer.register(JMX_COMPONENT_MAILBOXCOPIER, 
mailboxCopierManagementMBean);
+                jmxServer.register(JMX_COMPONENT_REINDEXER, 
reIndexerManagementMBean);
+                jmxServer.register(JMX_COMPONENT_QUOTA, quotaManagementMBean);
+                jmxServer.register(JMX_COMPONENT_SIEVE, 
sieveRepositoryManagementMBean);
+            });
     }
-
 }
diff --git 
a/server/container/guice/jpa-common-guice/src/main/java/org/apache/james/modules/data/JPADomainListModule.java
 
b/server/container/guice/jpa-common-guice/src/main/java/org/apache/james/modules/data/JPADomainListModule.java
index a1a5bca..b675f70 100644
--- 
a/server/container/guice/jpa-common-guice/src/main/java/org/apache/james/modules/data/JPADomainListModule.java
+++ 
b/server/container/guice/jpa-common-guice/src/main/java/org/apache/james/modules/data/JPADomainListModule.java
@@ -22,24 +22,21 @@ import 
org.apache.commons.configuration2.ex.ConfigurationException;
 import org.apache.james.domainlist.api.DomainList;
 import org.apache.james.domainlist.jpa.JPADomainList;
 import org.apache.james.domainlist.lib.DomainListConfiguration;
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Provides;
 import com.google.inject.Scopes;
 import com.google.inject.Singleton;
-import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class JPADomainListModule extends AbstractModule {
-
     @Override
     public void configure() {
         bind(JPADomainList.class).in(Scopes.SINGLETON);
         bind(DomainList.class).to(JPADomainList.class);
-        Multibinder.newSetBinder(binder(), 
InitializationOperation.class).addBinding().to(JPADomainListInitializationOperation.class);
     }
 
     @Provides
@@ -51,26 +48,11 @@ public class JPADomainListModule extends AbstractModule {
             throw new RuntimeException(e);
         }
     }
-    
-    @Singleton
-    public static class JPADomainListInitializationOperation implements 
InitializationOperation {
-        private final DomainListConfiguration configuration;
-        private final JPADomainList jpaDomainList;
-
-        @Inject
-        public JPADomainListInitializationOperation(DomainListConfiguration 
configuration, JPADomainList jpaDomainList) {
-            this.configuration = configuration;
-            this.jpaDomainList = jpaDomainList;
-        }
 
-        @Override
-        public void initModule() throws Exception {
-            jpaDomainList.configure(configuration);
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return JPADomainList.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation configureDomainList(DomainListConfiguration 
configuration, JPADomainList jpaDomainList) {
+        return InitilizationOperationBuilder
+            .forClass(JPADomainList.class)
+            .init(() -> jpaDomainList.configure(configuration));
     }
 }
diff --git 
a/server/container/guice/jpa-common-guice/src/main/java/org/apache/james/modules/data/JPARecipientRewriteTableModule.java
 
b/server/container/guice/jpa-common-guice/src/main/java/org/apache/james/modules/data/JPARecipientRewriteTableModule.java
index c57f1ff..b0456f1 100644
--- 
a/server/container/guice/jpa-common-guice/src/main/java/org/apache/james/modules/data/JPARecipientRewriteTableModule.java
+++ 
b/server/container/guice/jpa-common-guice/src/main/java/org/apache/james/modules/data/JPARecipientRewriteTableModule.java
@@ -18,47 +18,27 @@
  ****************************************************************/
 package org.apache.james.modules.data;
 
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.rrt.api.RecipientRewriteTable;
 import org.apache.james.rrt.jpa.JPARecipientRewriteTable;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Scopes;
-import com.google.inject.Singleton;
-import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class JPARecipientRewriteTableModule extends AbstractModule {
-
     @Override
     public void configure() {
         bind(JPARecipientRewriteTable.class).in(Scopes.SINGLETON);
         bind(RecipientRewriteTable.class).to(JPARecipientRewriteTable.class);
-        Multibinder.newSetBinder(binder(), 
InitializationOperation.class).addBinding().to(JPARecipientRewriteTablePerformer.class);
     }
 
-    @Singleton
-    public static class JPARecipientRewriteTablePerformer implements 
InitializationOperation {
-        private final ConfigurationProvider configurationProvider;
-        private final JPARecipientRewriteTable recipientRewriteTable;
-
-        @Inject
-        public JPARecipientRewriteTablePerformer(ConfigurationProvider 
configurationProvider, JPARecipientRewriteTable recipientRewriteTable) {
-            this.configurationProvider = configurationProvider;
-            this.recipientRewriteTable = recipientRewriteTable;
-        }
-
-        @Override
-        public void initModule() throws Exception {
-            
recipientRewriteTable.configure(configurationProvider.getConfiguration("recipientrewritetable"));
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return JPARecipientRewriteTable.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation configureRRT(ConfigurationProvider 
configurationProvider, JPARecipientRewriteTable recipientRewriteTable) {
+        return InitilizationOperationBuilder
+            .forClass(JPARecipientRewriteTable.class)
+            .init(() -> 
recipientRewriteTable.configure(configurationProvider.getConfiguration("recipientrewritetable")));
     }
-
 }
diff --git 
a/server/container/guice/jpa-common-guice/src/main/java/org/apache/james/modules/data/JPAUsersRepositoryModule.java
 
b/server/container/guice/jpa-common-guice/src/main/java/org/apache/james/modules/data/JPAUsersRepositoryModule.java
index 5618705..5a71924 100644
--- 
a/server/container/guice/jpa-common-guice/src/main/java/org/apache/james/modules/data/JPAUsersRepositoryModule.java
+++ 
b/server/container/guice/jpa-common-guice/src/main/java/org/apache/james/modules/data/JPAUsersRepositoryModule.java
@@ -18,47 +18,27 @@
  ****************************************************************/
 package org.apache.james.modules.data;
 
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.jpa.JPAUsersRepository;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Scopes;
-import com.google.inject.Singleton;
-import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class JPAUsersRepositoryModule extends AbstractModule {
     @Override
     public void configure() {
         bind(JPAUsersRepository.class).in(Scopes.SINGLETON);
         bind(UsersRepository.class).to(JPAUsersRepository.class);
-
-        Multibinder.newSetBinder(binder(), 
InitializationOperation.class).addBinding().to(JPAUsersRepositoryInitializationOperation.class);
     }
 
-    @Singleton
-    public static class JPAUsersRepositoryInitializationOperation implements 
InitializationOperation {
-        private final ConfigurationProvider configurationProvider;
-        private final JPAUsersRepository usersRepository;
-
-        @Inject
-        public JPAUsersRepositoryInitializationOperation(ConfigurationProvider 
configurationProvider, JPAUsersRepository usersRepository) {
-            this.configurationProvider = configurationProvider;
-            this.usersRepository = usersRepository;
-        }
-
-        @Override
-        public void initModule() throws Exception {
-            
usersRepository.configure(configurationProvider.getConfiguration("usersrepository"));
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return JPAUsersRepository.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation configureJpaUsers(ConfigurationProvider 
configurationProvider, JPAUsersRepository usersRepository) {
+        return InitilizationOperationBuilder
+            .forClass(JPAUsersRepository.class)
+            .init(() -> 
usersRepository.configure(configurationProvider.getConfiguration("usersrepository")));
     }
-
 }
diff --git 
a/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/DefaultEventModule.java
 
b/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/DefaultEventModule.java
index ea4b011..8e4d141 100644
--- 
a/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/DefaultEventModule.java
+++ 
b/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/DefaultEventModule.java
@@ -19,10 +19,7 @@
 
 package org.apache.james.modules.mailbox;
 
-import javax.inject.Inject;
-
 import org.apache.commons.configuration2.ex.ConfigurationException;
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.mailbox.events.EventBus;
 import org.apache.james.mailbox.events.InVMEventBus;
 import org.apache.james.mailbox.events.MailboxListener;
@@ -33,18 +30,18 @@ import org.apache.james.modules.EventDeadLettersProbe;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.utils.GuiceProbe;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 
 import com.google.inject.AbstractModule;
 import com.google.inject.Provides;
 import com.google.inject.Scopes;
 import com.google.inject.Singleton;
 import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class DefaultEventModule extends AbstractModule {
     @Override
     protected void configure() {
-        Multibinder.newSetBinder(binder(), 
InitializationOperation.class).addBinding().to(ListenerRegistrationPerformer.class);
-
         bind(MailboxListenerFactory.class).in(Scopes.SINGLETON);
         bind(MailboxListenersLoaderImpl.class).in(Scopes.SINGLETON);
         bind(InVmEventDelivery.class).in(Scopes.SINGLETON);
@@ -66,25 +63,10 @@ public class DefaultEventModule extends AbstractModule {
         return 
ListenersConfiguration.from(configurationProvider.getConfiguration("listeners"));
     }
 
-    @Singleton
-    public static class ListenerRegistrationPerformer implements 
InitializationOperation {
-        private final MailboxListenersLoaderImpl listeners;
-        private final ListenersConfiguration configuration;
-
-        @Inject
-        public ListenerRegistrationPerformer(MailboxListenersLoaderImpl 
listeners, ListenersConfiguration configuration) {
-            this.listeners = listeners;
-            this.configuration = configuration;
-        }
-
-        @Override
-        public void initModule() {
-            listeners.configure(configuration);
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return MailboxListenersLoaderImpl.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation registerListeners(MailboxListenersLoaderImpl 
listeners, ListenersConfiguration configuration) {
+        return InitilizationOperationBuilder
+            .forClass(MailboxListenersLoaderImpl.class)
+            .init(() -> listeners.configure(configuration));
     }
 }
diff --git 
a/server/container/guice/mailet/src/main/java/org/apache/james/modules/server/CamelMailetContainerModule.java
 
b/server/container/guice/mailet/src/main/java/org/apache/james/modules/server/CamelMailetContainerModule.java
index 39fe4e2..3df1755 100644
--- 
a/server/container/guice/mailet/src/main/java/org/apache/james/modules/server/CamelMailetContainerModule.java
+++ 
b/server/container/guice/mailet/src/main/java/org/apache/james/modules/server/CamelMailetContainerModule.java
@@ -47,6 +47,7 @@ import org.apache.james.utils.GuiceMailetLoader;
 import org.apache.james.utils.GuiceMatcherLoader;
 import org.apache.james.utils.GuiceProbe;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 import org.apache.james.utils.MailetConfigurationOverride;
 import org.apache.james.utils.SpoolerProbe;
 import org.apache.mailet.Mailet;
@@ -62,6 +63,7 @@ import com.google.inject.Provides;
 import com.google.inject.Scopes;
 import com.google.inject.Singleton;
 import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class CamelMailetContainerModule extends AbstractModule {
 
@@ -91,8 +93,6 @@ public class CamelMailetContainerModule extends 
AbstractModule {
         Multibinder.newSetBinder(binder(), 
GuiceProbe.class).addBinding().to(SpoolerProbe.class);
         Multibinder<InitializationOperation> initialisationOperations = 
Multibinder.newSetBinder(binder(), InitializationOperation.class);
         
initialisationOperations.addBinding().to(MailetModuleInitializationOperation.class);
-        initialisationOperations.addBinding().to(SpoolerStarter.class);
-        
initialisationOperations.addBinding().to(MailetContextInitializationOperation.class);
 
         Multibinder<CamelMailetContainerModule.TransportProcessorCheck> 
transportProcessorChecks = Multibinder.newSetBinder(binder(), 
CamelMailetContainerModule.TransportProcessorCheck.class);
         transportProcessorChecks.addBinding().toInstance(BCC_Check);
@@ -107,68 +107,40 @@ public class CamelMailetContainerModule extends 
AbstractModule {
         return camelContext;
     }
 
-    @Singleton
-    public static class SpoolerStarter implements InitializationOperation {
-        private final JamesMailSpooler jamesMailSpooler;
-        private final ConfigurationProvider configurationProvider;
-
-        @Inject
-        public SpoolerStarter(JamesMailSpooler jamesMailSpooler, 
ConfigurationProvider configurationProvider) {
-            this.jamesMailSpooler = jamesMailSpooler;
-            this.configurationProvider = configurationProvider;
-        }
-
-        @Override
-        public void initModule() {
-            jamesMailSpooler.configure(getJamesSpoolerConfiguration());
-            jamesMailSpooler.init();
-        }
-
-        private HierarchicalConfiguration<ImmutableNode> 
getJamesSpoolerConfiguration() {
-            try {
-                return 
configurationProvider.getConfiguration("mailetcontainer")
-                    .configurationAt("spooler");
-            } catch (Exception e) {
-                LOGGER.warn("Could not locate configuration for James Spooler. 
Assuming empty configuration for this component.");
-                return new BaseHierarchicalConfiguration();
-            }
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return JamesMailSpooler.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation startSpooler(JamesMailSpooler jamesMailSpooler, 
ConfigurationProvider configurationProvider) {
+        return InitilizationOperationBuilder
+            .forClass(JamesMailSpooler.class)
+            .init(() -> {
+                
jamesMailSpooler.configure(getJamesSpoolerConfiguration(configurationProvider));
+                jamesMailSpooler.init();
+            });
     }
 
-    @Singleton
-    public static class MailetContextInitializationOperation implements 
InitializationOperation {
-        private final ConfigurationProvider configurationProvider;
-        private final JamesMailetContext mailetContext;
-
-        @Inject
-        public MailetContextInitializationOperation(ConfigurationProvider 
configurationProvider, JamesMailetContext mailetContext) {
-            this.configurationProvider = configurationProvider;
-            this.mailetContext = mailetContext;
-        }
-
-        @Override
-        public void initModule() throws Exception {
-            mailetContext.configure(getMailetContextConfiguration());
+    private HierarchicalConfiguration<ImmutableNode> 
getJamesSpoolerConfiguration(ConfigurationProvider configurationProvider) {
+        try {
+            return configurationProvider.getConfiguration("mailetcontainer")
+                .configurationAt("spooler");
+        } catch (Exception e) {
+            LOGGER.warn("Could not locate configuration for James Spooler. 
Assuming empty configuration for this component.");
+            return new BaseHierarchicalConfiguration();
         }
+    }
 
-        private HierarchicalConfiguration<ImmutableNode> 
getMailetContextConfiguration() {
-            try {
-                return 
configurationProvider.getConfiguration("mailetcontainer")
-                    .configurationAt("context");
-            } catch (Exception e) {
-                LOGGER.warn("Could not locate configuration for Mailet 
context. Assuming empty configuration for this component.");
-                return new BaseHierarchicalConfiguration();
-            }
-        }
+    @ProvidesIntoSet
+    InitializationOperation initMailetContext(ConfigurationProvider 
configurationProvider, JamesMailetContext mailetContext) {
+        return InitilizationOperationBuilder
+            .forClass(JamesMailetContext.class)
+            .init(() -> 
mailetContext.configure(getMailetContextConfiguration(configurationProvider)));
+    }
 
-        @Override
-        public Class<? extends Startable> forClass() {
-            return JamesMailetContext.class;
+    private HierarchicalConfiguration<ImmutableNode> 
getMailetContextConfiguration(ConfigurationProvider configurationProvider) {
+        try {
+            return configurationProvider.getConfiguration("mailetcontainer")
+                .configurationAt("context");
+        } catch (Exception e) {
+            LOGGER.warn("Could not locate configuration for Mailet context. 
Assuming empty configuration for this component.");
+            return new BaseHierarchicalConfiguration();
         }
     }
 
diff --git 
a/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java
 
b/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java
index 0f867d8..5914a08 100644
--- 
a/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java
+++ 
b/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java
@@ -26,7 +26,6 @@ import 
org.apache.james.dlp.eventsourcing.EventSourcingDLPConfigurationStore;
 import org.apache.james.domainlist.api.DomainList;
 import org.apache.james.domainlist.lib.DomainListConfiguration;
 import org.apache.james.domainlist.memory.MemoryDomainList;
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.mailrepository.api.MailRepositoryUrlStore;
 import org.apache.james.mailrepository.api.Protocol;
 import org.apache.james.mailrepository.memory.MailRepositoryStoreConfiguration;
@@ -39,14 +38,14 @@ import 
org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.memory.MemoryUsersRepository;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 
 import com.google.common.collect.ImmutableList;
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Provides;
 import com.google.inject.Scopes;
 import com.google.inject.Singleton;
-import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class MemoryDataModule extends AbstractModule {
     private static final MailRepositoryStoreConfiguration.Item 
MEMORY_MAILREPOSITORY_DEFAULT_DECLARATION = new 
MailRepositoryStoreConfiguration.Item(
@@ -76,10 +75,6 @@ public class MemoryDataModule extends AbstractModule {
         bind(EventSourcingDLPConfigurationStore.class).in(Scopes.SINGLETON);
         
bind(DLPConfigurationStore.class).to(EventSourcingDLPConfigurationStore.class);
 
-        Multibinder<InitializationOperation> initialisationOperations = 
Multibinder.newSetBinder(binder(), InitializationOperation.class);
-        
initialisationOperations.addBinding().to(MemoryRRTInitializationOperation.class);
-        
initialisationOperations.addBinding().to(MemoryDomainListInitializationOperation.class);
-
         
bind(MailStoreRepositoryModule.DefaultItemSupplier.class).toInstance(() -> 
MEMORY_MAILREPOSITORY_DEFAULT_DECLARATION);
     }
 
@@ -93,47 +88,17 @@ public class MemoryDataModule extends AbstractModule {
         }
     }
 
-    @Singleton
-    public static class MemoryDomainListInitializationOperation implements 
InitializationOperation {
-        private final DomainListConfiguration domainListConfiguration;
-        private final MemoryDomainList memoryDomainList;
-
-        @Inject
-        public MemoryDomainListInitializationOperation(DomainListConfiguration 
domainListConfiguration, MemoryDomainList memoryDomainList) {
-            this.domainListConfiguration = domainListConfiguration;
-            this.memoryDomainList = memoryDomainList;
-        }
-
-        @Override
-        public void initModule() throws Exception {
-            memoryDomainList.configure(domainListConfiguration);
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return MemoryDomainList.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation configureDomainList(DomainListConfiguration 
domainListConfiguration, MemoryDomainList memoryDomainList) {
+        return InitilizationOperationBuilder
+            .forClass(MemoryDomainList.class)
+            .init(() -> memoryDomainList.configure(domainListConfiguration));
     }
 
-    @Singleton
-    public static class MemoryRRTInitializationOperation implements 
InitializationOperation {
-        private final ConfigurationProvider configurationProvider;
-        private final MemoryRecipientRewriteTable memoryRecipientRewriteTable;
-
-        @Inject
-        public MemoryRRTInitializationOperation(ConfigurationProvider 
configurationProvider, MemoryRecipientRewriteTable memoryRecipientRewriteTable) 
{
-            this.configurationProvider = configurationProvider;
-            this.memoryRecipientRewriteTable = memoryRecipientRewriteTable;
-        }
-
-        @Override
-        public void initModule() throws Exception {
-            
memoryRecipientRewriteTable.configure(configurationProvider.getConfiguration("recipientrewritetable"));
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return MemoryRecipientRewriteTable.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation configureRRT(ConfigurationProvider 
configurationProvider, MemoryRecipientRewriteTable memoryRecipientRewriteTable) 
{
+        return InitilizationOperationBuilder
+            .forClass(MemoryRecipientRewriteTable.class)
+            .init(() -> 
memoryRecipientRewriteTable.configure(configurationProvider.getConfiguration("recipientrewritetable")));
     }
 }
diff --git 
a/server/container/guice/protocols/imap/src/main/java/org/apache/james/modules/protocols/IMAPServerModule.java
 
b/server/container/guice/protocols/imap/src/main/java/org/apache/james/modules/protocols/IMAPServerModule.java
index 53f1cfb..16d738b 100644
--- 
a/server/container/guice/protocols/imap/src/main/java/org/apache/james/modules/protocols/IMAPServerModule.java
+++ 
b/server/container/guice/protocols/imap/src/main/java/org/apache/james/modules/protocols/IMAPServerModule.java
@@ -26,7 +26,6 @@ import org.apache.james.imap.main.DefaultImapDecoderFactory;
 import org.apache.james.imap.processor.main.DefaultImapProcessorFactory;
 import org.apache.james.imapserver.netty.IMAPServerFactory;
 import org.apache.james.imapserver.netty.OioIMAPServerFactory;
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.SubscriptionManager;
 import org.apache.james.mailbox.events.EventBus;
@@ -36,13 +35,14 @@ import org.apache.james.metrics.api.MetricFactory;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.utils.GuiceProbe;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Provides;
 import com.google.inject.Scopes;
 import com.google.inject.Singleton;
 import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class IMAPServerModule extends AbstractModule {
 
@@ -51,7 +51,6 @@ public class IMAPServerModule extends AbstractModule {
         bind(IMAPServerFactory.class).in(Scopes.SINGLETON);
         bind(OioIMAPServerFactory.class).in(Scopes.SINGLETON);
 
-        Multibinder.newSetBinder(binder(), 
InitializationOperation.class).addBinding().to(IMAPModuleInitializationOperation.class);
         Multibinder.newSetBinder(binder(), 
GuiceProbe.class).addBinding().to(ImapGuiceProbe.class);
     }
 
@@ -85,27 +84,13 @@ public class IMAPServerModule extends AbstractModule {
         return new DefaultImapEncoderFactory().buildImapEncoder();
     }
 
-    @Singleton
-    public static class IMAPModuleInitializationOperation implements 
InitializationOperation {
-
-        private final ConfigurationProvider configurationProvider;
-        private final IMAPServerFactory imapServerFactory;
-
-        @Inject
-        public IMAPModuleInitializationOperation(ConfigurationProvider 
configurationProvider, IMAPServerFactory imapServerFactory) {
-            this.configurationProvider = configurationProvider;
-            this.imapServerFactory = imapServerFactory;
-        }
-
-        @Override
-        public void initModule() throws Exception {
-            
imapServerFactory.configure(configurationProvider.getConfiguration("imapserver"));
-            imapServerFactory.init();
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return IMAPServerFactory.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation configureImap(ConfigurationProvider 
configurationProvider, IMAPServerFactory imapServerFactory) {
+        return InitilizationOperationBuilder
+            .forClass(IMAPServerFactory.class)
+            .init(() -> {
+                
imapServerFactory.configure(configurationProvider.getConfiguration("imapserver"));
+                imapServerFactory.init();
+            });
     }
 }
\ No newline at end of file
diff --git 
a/server/container/guice/protocols/jmap-draft/src/main/java/org/apache/james/modules/protocols/JMAPDraftServerModule.java
 
b/server/container/guice/protocols/jmap-draft/src/main/java/org/apache/james/modules/protocols/JMAPDraftServerModule.java
index bcfa7de..0cf3ebf 100644
--- 
a/server/container/guice/protocols/jmap-draft/src/main/java/org/apache/james/modules/protocols/JMAPDraftServerModule.java
+++ 
b/server/container/guice/protocols/jmap-draft/src/main/java/org/apache/james/modules/protocols/JMAPDraftServerModule.java
@@ -27,56 +27,39 @@ import org.apache.james.jmap.draft.JMAPServer;
 import org.apache.james.jmap.draft.JmapGuiceProbe;
 import org.apache.james.jmap.draft.MessageIdProbe;
 import org.apache.james.jmap.draft.crypto.JamesSignatureHandler;
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.utils.GuiceProbe;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 import org.bouncycastle.jce.provider.BouncyCastleProvider;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
 import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class JMAPDraftServerModule extends AbstractModule {
 
     @Override
     protected void configure() {
         install(new JMAPModule());
-        Multibinder.newSetBinder(binder(), 
InitializationOperation.class).addBinding().to(JMAPModuleInitializationOperation.class);
         Multibinder.newSetBinder(binder(), 
GuiceProbe.class).addBinding().to(JmapGuiceProbe.class);
         Multibinder.newSetBinder(binder(), 
GuiceProbe.class).addBinding().to(MessageIdProbe.class);
     }
 
-    @Singleton
-    public static class JMAPModuleInitializationOperation implements 
InitializationOperation {
-        private final JMAPServer server;
-        private final JamesSignatureHandler signatureHandler;
-        private final JMAPConfiguration jmapConfiguration;
 
-        @Inject
-        public JMAPModuleInitializationOperation(JMAPServer server, 
JamesSignatureHandler signatureHandler, JMAPConfiguration jmapConfiguration) {
-            this.server = server;
-            this.signatureHandler = signatureHandler;
-            this.jmapConfiguration = jmapConfiguration;
-        }
-
-        @Override
-        public void initModule() throws Exception {
-            if (jmapConfiguration.isEnabled()) {
-                signatureHandler.init();
-                server.start();
-                registerPEMWithSecurityProvider();
-            }
-        }
-
-        private void registerPEMWithSecurityProvider() {
-            Security.addProvider(new BouncyCastleProvider());
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return JMAPServer.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation startJmap(JMAPServer server, JamesSignatureHandler 
signatureHandler, JMAPConfiguration jmapConfiguration) {
+        return InitilizationOperationBuilder
+            .forClass(JMAPServer.class)
+            .init(() -> {
+                if (jmapConfiguration.isEnabled()) {
+                    signatureHandler.init();
+                    server.start();
+                    registerPEMWithSecurityProvider();
+                }
+            });
     }
 
+    private void registerPEMWithSecurityProvider() {
+        Security.addProvider(new BouncyCastleProvider());
+    }
 }
diff --git 
a/server/container/guice/protocols/lmtp/src/main/java/org/apache/james/modules/protocols/LMTPServerModule.java
 
b/server/container/guice/protocols/lmtp/src/main/java/org/apache/james/modules/protocols/LMTPServerModule.java
index 798dbf7..4d40003 100644
--- 
a/server/container/guice/protocols/lmtp/src/main/java/org/apache/james/modules/protocols/LMTPServerModule.java
+++ 
b/server/container/guice/protocols/lmtp/src/main/java/org/apache/james/modules/protocols/LMTPServerModule.java
@@ -19,53 +19,35 @@
 
 package org.apache.james.modules.protocols;
 
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.lmtpserver.netty.LMTPServerFactory;
 import org.apache.james.lmtpserver.netty.OioLMTPServerFactory;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.util.LoggingLevel;
 import org.apache.james.utils.GuiceProbe;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Scopes;
-import com.google.inject.Singleton;
 import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class LMTPServerModule extends AbstractModule {
-
     @Override
     protected void configure() {
         bind(LMTPServerFactory.class).in(Scopes.SINGLETON);
         bind(OioLMTPServerFactory.class).in(Scopes.SINGLETON);
 
-        Multibinder.newSetBinder(binder(), 
InitializationOperation.class).addBinding().to(LMTPModuleInitializationOperation.class);
         Multibinder.newSetBinder(binder(), 
GuiceProbe.class).addBinding().to(LmtpGuiceProbe.class);
     }
 
-    @Singleton
-    public static class LMTPModuleInitializationOperation implements 
InitializationOperation {
-
-        private final ConfigurationProvider configurationProvider;
-        private final LMTPServerFactory lmtpServerFactory;
-
-        @Inject
-        public LMTPModuleInitializationOperation(ConfigurationProvider 
configurationProvider, LMTPServerFactory lmtpServerFactory) {
-            this.configurationProvider = configurationProvider;
-            this.lmtpServerFactory = lmtpServerFactory;
-        }
-
-        @Override
-        public void initModule() throws Exception {
-            
lmtpServerFactory.configure(configurationProvider.getConfiguration("lmtpserver",
 LoggingLevel.INFO));
-            lmtpServerFactory.init();
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return LMTPServerFactory.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation configureLmtp(ConfigurationProvider 
configurationProvider, LMTPServerFactory lmtpServerFactory) {
+        return InitilizationOperationBuilder
+            .forClass(LMTPServerFactory.class)
+            .init(() -> {
+                
lmtpServerFactory.configure(configurationProvider.getConfiguration("lmtpserver",
 LoggingLevel.INFO));
+                lmtpServerFactory.init();
+            });
     }
-
 }
diff --git 
a/server/container/guice/protocols/managedsieve/src/main/java/org/apache/james/modules/protocols/ManageSieveServerModule.java
 
b/server/container/guice/protocols/managedsieve/src/main/java/org/apache/james/modules/protocols/ManageSieveServerModule.java
index a0be505..28b29cc 100644
--- 
a/server/container/guice/protocols/managedsieve/src/main/java/org/apache/james/modules/protocols/ManageSieveServerModule.java
+++ 
b/server/container/guice/protocols/managedsieve/src/main/java/org/apache/james/modules/protocols/ManageSieveServerModule.java
@@ -18,7 +18,6 @@
  ****************************************************************/
 package org.apache.james.modules.protocols;
 
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.managesieve.api.commands.CoreCommands;
 import org.apache.james.managesieve.core.CoreProcessor;
 import org.apache.james.managesieveserver.netty.ManageSieveServerFactory;
@@ -26,11 +25,11 @@ import 
org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.util.LoggingLevel;
 import org.apache.james.utils.GuiceProbe;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
 import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class ManageSieveServerModule extends AbstractModule {
 
@@ -38,30 +37,16 @@ public class ManageSieveServerModule extends AbstractModule 
{
     protected void configure() {
         install(new SieveModule());
         bind(CoreCommands.class).to(CoreProcessor.class);
-        Multibinder.newSetBinder(binder(), 
InitializationOperation.class).addBinding().to(ManageSieveModuleInitializationOperation.class);
         Multibinder.newSetBinder(binder(), 
GuiceProbe.class).addBinding().to(SieveProbeImpl.class);
     }
 
-    @Singleton
-    public static class ManageSieveModuleInitializationOperation implements 
InitializationOperation {
-        private final ConfigurationProvider configurationProvider;
-        private final ManageSieveServerFactory manageSieveServerFactory;
-
-        @Inject
-        public ManageSieveModuleInitializationOperation(ConfigurationProvider 
configurationProvider, ManageSieveServerFactory manageSieveServerFactory) {
-            this.configurationProvider = configurationProvider;
-            this.manageSieveServerFactory = manageSieveServerFactory;
-        }
-
-        @Override
-        public void initModule() throws Exception {
-            
manageSieveServerFactory.configure(configurationProvider.getConfiguration("managesieveserver",
 LoggingLevel.INFO));
-            manageSieveServerFactory.init();
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return ManageSieveServerFactory.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation configureManageSieve(ConfigurationProvider 
configurationProvider, ManageSieveServerFactory manageSieveServerFactory) {
+        return InitilizationOperationBuilder
+            .forClass(ManageSieveServerFactory.class)
+            .init(() -> {
+                
manageSieveServerFactory.configure(configurationProvider.getConfiguration("managesieveserver",
 LoggingLevel.INFO));
+                manageSieveServerFactory.init();
+            });
     }
 }
\ No newline at end of file
diff --git 
a/server/container/guice/protocols/pop/src/main/java/org/apache/james/modules/protocols/POP3ServerModule.java
 
b/server/container/guice/protocols/pop/src/main/java/org/apache/james/modules/protocols/POP3ServerModule.java
index fd769b2..ad1a808 100644
--- 
a/server/container/guice/protocols/pop/src/main/java/org/apache/james/modules/protocols/POP3ServerModule.java
+++ 
b/server/container/guice/protocols/pop/src/main/java/org/apache/james/modules/protocols/POP3ServerModule.java
@@ -19,51 +19,34 @@
 
 package org.apache.james.modules.protocols;
 
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.pop3server.netty.OioPOP3ServerFactory;
 import org.apache.james.pop3server.netty.POP3ServerFactory;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.utils.GuiceProbe;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Scopes;
-import com.google.inject.Singleton;
 import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class POP3ServerModule extends AbstractModule {
-
     @Override
     protected void configure() {
         bind(POP3ServerFactory.class).in(Scopes.SINGLETON);
         bind(OioPOP3ServerFactory.class).in(Scopes.SINGLETON);
 
-        Multibinder.newSetBinder(binder(), 
InitializationOperation.class).addBinding().to(POP3ModuleInitializationOperation.class);
         Multibinder.newSetBinder(binder(), 
GuiceProbe.class).addBinding().to(Pop3GuiceProbe.class);
     }
 
-    @Singleton
-    public static class POP3ModuleInitializationOperation implements 
InitializationOperation {
-        private final ConfigurationProvider configurationProvider;
-        private final POP3ServerFactory pop3ServerFactory;
-
-        @Inject
-        public POP3ModuleInitializationOperation(ConfigurationProvider 
configurationProvider, POP3ServerFactory pop3ServerFactory) {
-            this.configurationProvider = configurationProvider;
-            this.pop3ServerFactory = pop3ServerFactory;
-        }
-
-        @Override
-        public void initModule() throws Exception {
-            
pop3ServerFactory.configure(configurationProvider.getConfiguration("pop3server"));
-            pop3ServerFactory.init();
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return POP3ServerFactory.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation configurePop3(ConfigurationProvider 
configurationProvider, POP3ServerFactory pop3ServerFactory) {
+        return InitilizationOperationBuilder
+            .forClass(POP3ServerFactory.class)
+            .init(() -> {
+                
pop3ServerFactory.configure(configurationProvider.getConfiguration("pop3server"));
+                pop3ServerFactory.init();
+            });
     }
-
 }
diff --git 
a/server/container/guice/protocols/smtp/src/main/java/org/apache/james/modules/protocols/SMTPServerModule.java
 
b/server/container/guice/protocols/smtp/src/main/java/org/apache/james/modules/protocols/SMTPServerModule.java
index 66cdd75..58b2e96 100644
--- 
a/server/container/guice/protocols/smtp/src/main/java/org/apache/james/modules/protocols/SMTPServerModule.java
+++ 
b/server/container/guice/protocols/smtp/src/main/java/org/apache/james/modules/protocols/SMTPServerModule.java
@@ -19,59 +19,40 @@
 
 package org.apache.james.modules.protocols;
 
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.smtpserver.SendMailHandler;
 import org.apache.james.smtpserver.netty.OioSMTPServerFactory;
 import org.apache.james.smtpserver.netty.SMTPServerFactory;
 import org.apache.james.utils.GuiceProbe;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Scopes;
-import com.google.inject.Singleton;
 import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class SMTPServerModule extends AbstractModule {
-
     @Override
     protected void configure() {
         install(new JSPFModule());
         bind(SMTPServerFactory.class).in(Scopes.SINGLETON);
         bind(OioSMTPServerFactory.class).in(Scopes.SINGLETON);
 
-        Multibinder.newSetBinder(binder(), 
InitializationOperation.class).addBinding().to(SMTPModuleInitializationOperation.class);
         Multibinder.newSetBinder(binder(), 
GuiceProbe.class).addBinding().to(SmtpGuiceProbe.class);
     }
 
-    @Singleton
-    public static class SMTPModuleInitializationOperation implements 
InitializationOperation {
-
-        private final ConfigurationProvider configurationProvider;
-        private final SMTPServerFactory smtpServerFactory;
-        private final SendMailHandler sendMailHandler;
-
-        @Inject
-        public SMTPModuleInitializationOperation(ConfigurationProvider 
configurationProvider,
-                                                 SMTPServerFactory 
smtpServerFactory,
-                                                 SendMailHandler 
sendMailHandler) {
-            this.configurationProvider = configurationProvider;
-            this.smtpServerFactory = smtpServerFactory;
-            this.sendMailHandler = sendMailHandler;
-        }
-
-        @Override
-        public void initModule() throws Exception {
+    @ProvidesIntoSet
+    InitializationOperation configureSmtp(ConfigurationProvider 
configurationProvider,
+                                        SMTPServerFactory smtpServerFactory,
+                                        SendMailHandler sendMailHandler) {
+        return InitilizationOperationBuilder
+            .forClass(SMTPServerFactory.class)
+            .init(() -> {
                 
smtpServerFactory.configure(configurationProvider.getConfiguration("smtpserver"));
                 smtpServerFactory.init();
                 sendMailHandler.init(null);
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return SMTPServerFactory.class;
-        }
+            });
     }
 
 }
diff --git 
a/server/container/guice/protocols/webadmin/src/main/java/org/apache/james/modules/server/WebAdminServerModule.java
 
b/server/container/guice/protocols/webadmin/src/main/java/org/apache/james/modules/server/WebAdminServerModule.java
index 87165f1..ff2f263 100644
--- 
a/server/container/guice/protocols/webadmin/src/main/java/org/apache/james/modules/server/WebAdminServerModule.java
+++ 
b/server/container/guice/protocols/webadmin/src/main/java/org/apache/james/modules/server/WebAdminServerModule.java
@@ -30,11 +30,11 @@ import javax.inject.Named;
 
 import org.apache.commons.configuration2.Configuration;
 import org.apache.james.jwt.JwtTokenVerifier;
-import org.apache.james.lifecycle.api.Startable;
 import org.apache.james.utils.ClassName;
 import org.apache.james.utils.GuiceGenericLoader;
 import org.apache.james.utils.GuiceProbe;
 import org.apache.james.utils.InitializationOperation;
+import org.apache.james.utils.InitilizationOperationBuilder;
 import org.apache.james.utils.NamingScheme;
 import org.apache.james.utils.PropertiesProvider;
 import org.apache.james.utils.WebAdminGuiceProbe;
@@ -55,11 +55,11 @@ import com.github.fge.lambdas.Throwing;
 import com.github.steveash.guavate.Guavate;
 import com.google.common.collect.ImmutableList;
 import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
 import com.google.inject.Provides;
 import com.google.inject.Scopes;
 import com.google.inject.Singleton;
 import com.google.inject.multibindings.Multibinder;
+import com.google.inject.multibindings.ProvidesIntoSet;
 
 public class WebAdminServerModule extends AbstractModule {
 
@@ -82,7 +82,6 @@ public class WebAdminServerModule extends AbstractModule {
         bind(JsonTransformer.class).in(Scopes.SINGLETON);
         bind(WebAdminServer.class).in(Scopes.SINGLETON);
 
-        Multibinder.newSetBinder(binder(), 
InitializationOperation.class).addBinding().to(WebAdminServerModuleInitializationOperation.class);
         Multibinder.newSetBinder(binder(), 
GuiceProbe.class).addBinding().to(WebAdminGuiceProbe.class);
         Multibinder.newSetBinder(binder(), JsonTransformerModule.class);
     }
@@ -157,24 +156,10 @@ public class WebAdminServerModule extends AbstractModule {
         return Optional.empty();
     }
 
-    @Singleton
-    public static class WebAdminServerModuleInitializationOperation implements 
InitializationOperation {
-        private final WebAdminServer webAdminServer;
-
-        @Inject
-        public WebAdminServerModuleInitializationOperation(WebAdminServer 
webAdminServer) {
-            this.webAdminServer = webAdminServer;
-        }
-
-        @Override
-        public void initModule() {
-            webAdminServer.start();
-        }
-
-        @Override
-        public Class<? extends Startable> forClass() {
-            return WebAdminServer.class;
-        }
+    @ProvidesIntoSet
+    InitializationOperation workQueue(WebAdminServer instance) {
+        return InitilizationOperationBuilder
+            .forClass(WebAdminServer.class)
+            .init(instance::start);
     }
-
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to