/*
 * Copyright (C) 2016-2017 Selerity, Inc. (support@seleritycorp.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.seleritycorp.common.base.inject;


import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;

import com.seleritycorp.common.base.config.ConfigModule;
import com.seleritycorp.common.base.config.ProductionModule;
import com.seleritycorp.common.base.http.client.HttpClientModule;
import com.seleritycorp.common.base.http.server.HttpServerModule;
import com.seleritycorp.common.base.logging.LoggingModule;
import com.seleritycorp.common.base.state.StateModule;
import com.seleritycorp.common.base.time.TimeModule;
import com.seleritycorp.common.base.uuid.UuidModule;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;

import java.util.ArrayList;
import java.util.List;

public class InjectorFactory {
  private static Injector injector = null;

  /**
   * Gets the current injector
   *
   * <p>The current injector is a point in time snapshot, and will not reflect
   * modules registered in the future.
   *
   * <p>If no injector has been set up, the production injector will be created.
   * 
   * @return The current injector.
   */
  @SuppressFBWarnings(value = "DC_DOUBLECHECK",
      justification = "Outer check is quick and unsynchronized. Inner check is synchronized")
  public static Injector getInjector() {
    if (injector == null) {
      synchronized (Injector.class) {
        if (injector == null) {
          List<Module> modules = new ArrayList<>(5);
          modules.add(new ProductionModule());
          modules.add(new TimeModule());
          modules.add(new ConfigModule());
          modules.add(new LoggingModule());
          modules.add(new StateModule());
          modules.add(new UuidModule());
          modules.add(new HttpClientModule());
          modules.add(new HttpServerModule());
          injector = Guice.createInjector(modules);
        }
      }
    }
    return injector;
  }

  /**
   * Registers an additional module
   *
   * <p>The current injector gets replaced by one that contains all the
   * previously registered module, and the currently passed one.
   * 
   * @param module The module to register
   * @return The new injector with the registered module.
   */
  public static Injector register(AbstractModule module) {
    Injector parent = getInjector();
    injector = parent.createChildInjector(module);
    return injector;
  }

  /**
   * Forces the factory to use the given
   *
   * <p>You should not need this method in production code. This is only useful
   * in tests.
   * 
   * @param injector The injector to force. If null, the injector gets
   *        reset, and re-initialized upon the getting anInjector next time.
   */
  public static void forceInjector(Injector injector) {
    synchronized (Injector.class) {
      InjectorFactory.injector = injector;
    }
  }
}

@@ -1288,68 +1288,8 @@
 e;%0A%0A
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;%0A%0A
 impo
@@ -1710,291 +1710,88 @@
 /%0A  
-@SuppressFBWarnings(value = %22DC_DOUBLECHECK%22,%0A      justification = %22Outer check is quick and unsynchronized. Inner check is synchronized%22)%0A  public static Injector getInjector() %7B%0A    if (injector == null) %7B%0A      synchronized (Injector.class) %7B%0A        if (injector == null) %7B%0A    
+public static synchronized Injector getInjector() %7B%0A    if (injector == null) %7B%0A
     
@@ -1833,36 +1833,32 @@
 ist%3C%3E(5);%0A      
-    
 modules.add(new 
@@ -1876,36 +1876,32 @@
 odule());%0A      
- 
-   
 modules.add(new 
@@ -1907,36 +1907,32 @@
  TimeModule());%0A
-    
       modules.ad
@@ -1952,36 +1952,32 @@
 odule());%0A      
- 
-   
 modules.add(new 
@@ -1992,36 +1992,32 @@
 odule());%0A      
-    
 modules.add(new 
@@ -2030,36 +2030,32 @@
 odule());%0A      
- 
-   
 modules.add(new 
@@ -2061,36 +2061,32 @@
  UuidModule());%0A
-    
       modules.ad
@@ -2118,20 +2118,16 @@
 ;%0A      
-  
-  
 modules.
@@ -2155,20 +2155,16 @@
 ule());%0A
-    
       in
@@ -2207,26 +2207,8 @@
 s);%0A
-        %7D%0A      %7D%0A
     
@@ -2539,32 +2539,45 @@
   public static 
+synchronized 
 Injector registe
@@ -3040,16 +3040,29 @@
  static 
+synchronized 
 void for
@@ -3097,46 +3097,8 @@
 ) %7B%0A
-    synchronized (Injector.class) %7B%0A  
     
@@ -3134,20 +3134,14 @@
 jector;%0A
-    %7D%0A
   %7D%0A%7D%0A

Make InjectorFactory's methods synchronized