/**
   * Stops the EJB3 server.
   *
   * @throws EmbeddedException if container cannot be stopped.
   */
  public synchronized void stop() throws EmbeddedException {
    // ensure started
    if (!this.started) {
      throw new EmbeddedException("Cannot stop the server as it is not started.");
    }
    this.stopping = true;

    if (this.dispatcher != null) {
      this.dispatcher.dispatch(new EventLifeCycleStopping(this.j2eeManagedObjectId));
    }

    // Stop the containers
    // Use a ListIterator to allow us to safely remove EZBContainers
    // from the List being processed.
    List<EZBContainer> containersList = new ArrayList<EZBContainer>(this.containers.values());
    ListIterator<EZBContainer> li = containersList.listIterator();
    while (li.hasNext()) {
      EZBContainer container = li.next();
      container.stop();
      removeContainer(container);
    }

    // Unregister MBeans
    if (this.serverConfig.isUsingMBeans()) {

      if (this.serverConfig.isStartJMXConnector()) {
        // Stop the JMX Connector
        try {
          JMXRemoteHelper.stopConnector();
        } catch (JMXRemoteException e) {
          // Only log the Exception

          // and continue ...
        }
      }

      // Unregister the Deployer
      if (this.serverConfig.isRegisterDeployerMBean()) {
        try {
          MBeansHelper.getInstance().unregisterMBean(this.deployer);
        } catch (MBeansException e) {
          // Only log the Exception

        }
      }

      // Unregister the Server
      if (this.serverConfig.isRegisterJ2EEServerMBean()) {
        try {
          MBeansHelper.getInstance().unregisterMBean(this);
        } catch (MBeansException e) {
          // Only log the Exception
        }
      }
    }

    // Unbind the RPCInvoker Remote Object
    try {
      new InitialContext().unbind(RMIServerRPC.RPC_JNDI_NAME);
    } catch (NamingException e) {
      // Only log the Exception
    }

    // Unexport
    try {
      PortableRemoteObject.unexportObject(this.invoker);
    } catch (NoSuchObjectException e) {
      // Only log the Exception
    }

    // Dispatch lifecycle event.
    this.dispatcher.dispatch(new EventLifeCycleStopped(this.j2eeManagedObjectId));

    // Unregister from statistic component.
    EZBStatisticComponent statisticComponent = getComponent(EZBStatisticComponent.class);
    if (statisticComponent != null) {
      statisticComponent.unregisterJ2EEManagedObject(this);
    }

    // Unregister from jmx component will be done by the mbean itself.

    // Unregister from event component.
    EZBEventComponent eventComponent = getComponent(EZBEventComponent.class);
    if (eventComponent != null) {
      eventComponent.unregisterJ2EEManagedObject(this);

      // Unregister the NamingExtensions (used to fill the java:comp Context)
      for (IEventListener extension : this.defaultNamingExtensions) {
        eventComponent.getEventService().unregisterListener(extension);
      }
    }

    // Destroy the event dispatcher.
    this.dispatcher.stop();
    this.dispatcher = null;

    // Stop the components
    if (this.serverConfig.isStopComponentsDuringShutdown()) {
      this.componentManager.stopComponents();
    }

    // Stop JACC
    if (this.serverConfig.initJACC()) {
      try {
        PolicyProvider.stop();
      } catch (Exception e) {
        // Only log the Exception
      }
    }

    // EasyBeans is stopped
    this.started = false;
    this.stopped = true;
    this.stopping = false;
  }
  /**
   * This is the topic where naming events will be send. Interested IEventListeners should register
   * to this topic.
   */
  public void start() throws EmbeddedException {
    this.stopping = false;

    long tStart = System.currentTimeMillis();

    // Deployer manager ?
    if (this.deployerManager == null) {
      this.deployerManager = new DeployerManager();
      EasyBeansDeployer easyBeansDeployer = new EasyBeansDeployerExt();
      easyBeansDeployer.setEmbedded(this);
      this.deployerManager.register(easyBeansDeployer);
    }

    // Add default components like Quartz Timer service, etc.
    if (!this.componentsInitialized) {
      if (this.serverConfig.addEmbeddedComponents()) {
        // Add the core configuration first
        this.serverConfig
            .getConfigurationURLs()
            .addFirst(Thread.currentThread().getContextClassLoader().getResource(CORE_XML_FILE));
      }

      // Configure the given embedded instance (= this)
      try {
        if (!this.serverConfig.getConfigurationURLs().isEmpty()) {}

        EmbeddedConfigurator.init(
            this,
            this.serverConfig.getConfigurationURLs(),
            this.serverConfig.getConfigurationMap());
      } catch (EmbeddedException e) {
        throw new EmbeddedException("Cannot configure the embedded server", e);
      }
      this.componentsInitialized = true;
    }

    // Init JACC
    if (this.serverConfig.initJACC()) {
      PolicyProvider.init();
    }

    // configure
    configureDeploy();

    if (this.serverConfig.isUsingNaming()) {
      // url.pkg for java:
      System.setProperty(Context.URL_PKG_PREFIXES, "org.ow2.easybeans.naming.pkg");
    }

    // set the deployer used for this component.
    try {
      this.deployer = new RemoteDeployer(this);
    } catch (DeployerException e) {
      throw new EmbeddedException("Cannot build a remote deployer.", e);
    }

    MBeansHelper.getInstance().activate(this.serverConfig.isUsingMBeans());
    if (this.serverConfig.isUsingMBeans()) {

      // init Modeler Registry
      try {
        CommonsModelerHelper.initRegistry();
      } catch (CommonsModelerException e) {
        throw new EmbeddedException("Cannot init MBean server", e);
      }

      // Start MBeanServer (if any)
      try {
        MBeanServerHelper.startMBeanServer();
      } catch (MBeanServerException e) {
        throw new EmbeddedException("Cannot start MBean server", e);
      }
    }

    if (this.serverConfig.isAutoConfigureComponents()) {
      // Init components
      try {
        this.componentManager.initComponents(!this.componentsRegistered);
      } catch (EZBComponentException e) {
        throw new EmbeddedException("Cannot init components", e);
      }
      this.componentsRegistered = true;

      // Start components
      try {
        this.componentManager.startComponents();
      } catch (EZBComponentException e) {
        throw new EmbeddedException("Cannot start components", e);
      }
    }

    // Create the event dispatcher
    this.dispatcher = new EventDispatcher();
    this.dispatcher.start();

    // Register to event component.
    EZBEventComponent eventComponent = getComponent(EZBEventComponent.class);
    if (eventComponent != null) {
      try {
        eventComponent.init();
      } catch (EZBComponentException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
      eventComponent.registerJ2EEManagedObject(this, this.dispatcher);
    }

    // Register to jmx component will be done by the mbean itself.

    // Register to statistic component.
    EZBStatisticComponent statisticComponent = getComponent(EZBStatisticComponent.class);
    if (statisticComponent != null) {
      statisticComponent.registerJ2EEManagedObject(this);
    }

    // Register some NamingExtension (used to fill the java:comp Context)
    if (eventComponent != null) {
      for (IEventListener extension : this.defaultNamingExtensions) {
        eventComponent.getEventService().registerListener(extension, NAMING_EXTENSION_POINT);
      }
    }

    // Dispatch life cycle event.
    this.dispatcher.dispatch(new EventLifeCycleStarting(this.j2eeManagedObjectId));

    if (this.serverConfig.isUsingMBeans()) {
      if (this.serverConfig.isStartJMXConnector()) {
        try {
          JMXRemoteHelper.startConnector(
              (RegistryComponent) getComponent("org.ow2.easybeans.component.carol.CarolComponent"));
        } catch (JMXRemoteException e) {
          throw new EmbeddedException("Cannot start JMX Remote connector", e);
        }
      }

      // register the Deployer
      if (this.serverConfig.isRegisterDeployerMBean()) {
        try {
          MBeansHelper.getInstance().registerMBean(this.deployer);
        } catch (MBeansException e) {
          throw new EmbeddedException("Cannot init MBeans", e);
        }
      }

      // register the Server
      /*if (this.serverConfig.isRegisterJ2EEServerMBean()) {
          try {
              MBeansHelper.getInstance().registerMBean(this);
          } catch (MBeansException e) {
              throw new EmbeddedException("Cannot init MBeans", e);
          }
      }*/
    }

    // Bind the RPC object
    try {
      this.invoker = new RMIServerRPCImpl(this);
    } catch (RemoteException e) {
      throw new EmbeddedException("Cannot build RPC invoker", e);
    }
    try {
      new InitialContext().rebind(RMIServerRPC.RPC_JNDI_NAME, this.invoker);
    } catch (NamingException e) {
      throw new EmbeddedException("Cannot bind the RPC invoker", e);
    }

    this.dispatcher.dispatch(new EventLifeCycleStarted(this.j2eeManagedObjectId));

    // It is started
    this.started = true;

    /*EZBDepMonitorComponent depMonitorComponent = getComponent(EZBDepMonitorComponent.class);
    if (depMonitorComponent != null) {
        try {
            depMonitorComponent.enable();
        } catch (EZBComponentException e) {

        }
    }*/
  }