package org.jboss.forge.container;

import java.util.concurrent.Callable;

import javax.enterprise.inject.spi.BeanManager;

import org.jboss.forge.container.ContainerControl;
import org.jboss.forge.container.Status;
import org.jboss.forge.container.event.ContainerShutdown;
import org.jboss.forge.container.event.ContainerStartup;
import org.jboss.forge.container.exception.ContainerException;
import org.jboss.forge.container.modules.ModularWeld;
import org.jboss.forge.container.modules.SilentTCCLSingletonProvider;
import org.jboss.forge.container.services.ServiceRegistry;
import org.jboss.forge.container.util.Assert;
import org.jboss.forge.container.util.BeanManagerUtils;
import org.jboss.forge.container.util.ClassLoaders;
import org.jboss.modules.Module;
import org.jboss.weld.bootstrap.api.SingletonProvider;
import org.jboss.weld.environment.se.Weld;
import org.jboss.weld.environment.se.WeldContainer;

public final class AddonRunnable implements Runnable
{
   private AddonImpl addon;
   private AddonRegistry addonRegistry;
   private boolean shutdown = false;

   public AddonRunnable(AddonImpl addon, AddonRegistry registry)
   {
      this.addon = addon;
      this.addonRegistry = registry;
   }

   public void shutdown()
   {
      this.shutdown = true;
   }

   @Override
   public void run()
   {
      final Module module = addon.getModule();

      ClassLoaders.executeIn(module.getClassLoader(), new Callable<Object>()
      {
         @Override
         public Object call() throws Exception
         {
            try
            {
               SingletonProvider.reset();
               SingletonProvider.initialize(new SilentTCCLSingletonProvider());

               Weld weld = new ModularWeld(module);
               WeldContainer container = weld.initialize();

               BeanManager manager = container.getBeanManager();
               Assert.notNull(manager, "BeanManager was null");

               addonRegistry.register(addon);
               addon.setStatus(Status.STARTING);

               manager.fireEvent(new ContainerStartup());
               
               ContainerControl control = BeanManagerUtils.getContextualInstance(manager, ContainerControl.class);
               Assert.notNull(control, "Container control was null.");

               if (!Status.STARTED.equals(control.getStatus()))
               {
                  throw new ContainerException("Container failed to start.");
               }

               ServiceRegistry registry = BeanManagerUtils.getContextualInstance(manager, ServiceRegistry.class);
               Assert.notNull(registry, "Service registry was null.");
               addon.setServiceRegistry(registry);

               addon.setStatus(Status.STARTED);

               System.out.println("Services loaded from addon module [" + module.getIdentifier() + "] - "
                        + registry.getServices());

               while (!shutdown)
               {
                  Thread.sleep(10);
               }

               addon.setStatus(Status.STOPPING);

               addonRegistry.remove(addon);
               manager.fireEvent(new ContainerShutdown());
               weld.shutdown();

               addon.setStatus(Status.STOPPED);
               return null;
            }
            catch (Exception e)
            {
               addon.setStatus(Status.FAILED);
               throw e;
            }
         }
      });
   }

   public AddonImpl getAddon()
   {
      return addon;
   }
}

@@ -963,16 +963,166 @@
 nable%0A%7B%0A
+   static%0A   %7B%0A      /*%0A       * This must happen once per JVM%0A       */%0A      SingletonProvider.initialize(new SilentTCCLSingletonProvider());%0A   %7D%0A%0A
    priva
@@ -1706,131 +1706,8 @@
   %7B%0A
-               SingletonProvider.reset();%0A               SingletonProvider.initialize(new SilentTCCLSingletonProvider());%0A%0A
     
@@ -2099,31 +2099,16 @@
 tup());%0A
-               
 %0A       

Fix SingletonProvider configuration