/**
 *
 * Copyright 2005 the original author or authors.
 *
 *  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 org.gbean.kernel.standard;

import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

import edu.emory.mathcs.backport.java.util.concurrent.Callable;
import edu.emory.mathcs.backport.java.util.concurrent.CountDownLatch;
import edu.emory.mathcs.backport.java.util.concurrent.ExecutionException;
import edu.emory.mathcs.backport.java.util.concurrent.FutureTask;
import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
import junit.framework.TestCase;
import org.gbean.kernel.IllegalServiceStateException;
import org.gbean.kernel.KernelErrorsError;
import org.gbean.kernel.ServiceAlreadyExistsException;
import org.gbean.kernel.ServiceFactory;
import org.gbean.kernel.ServiceName;
import org.gbean.kernel.ServiceNotFoundException;
import org.gbean.kernel.ServiceRegistrationException;
import org.gbean.kernel.StaticServiceFactory;
import org.gbean.kernel.StopStrategies;
import org.gbean.kernel.StopStrategy;
import org.gbean.kernel.StringServiceName;
import org.gbean.kernel.UnsatisfiedConditionsException;

/**
 * Test the ServiceManagerRegistry.
 *
 * @author Dain Sundstrom
 * @version $Id$
 * @since 1.0
 */
public class ServiceManagerRegistryTest extends TestCase {
    private static final int TIMEOUT_DURATION = 5;
    private static final TimeUnit TIMEOUT_UNITS = TimeUnit.SECONDS;

    private static final StringServiceName SERVICE_NAME = new StringServiceName("Service");
    private static final StaticServiceFactory SERVICE_FACTORY = new StaticServiceFactory(new Object());
    private static final ClassLoader CLASS_LOADER = new URLClassLoader(new URL[0]);
    private final MockServiceManager serviceManager = new MockServiceManager();
    private final MockServiceManagerFactory serviceManagerFactory = new MockServiceManagerFactory();
    private final ServiceManagerRegistry registry = new ServiceManagerRegistry(serviceManagerFactory);

    /**
     * Tests the initial state of the registry.
     */
    public void testInitialState() {
        assertFalse(registry.isRegistered(SERVICE_NAME));
        try {
            assertNull(registry.getServiceManager(SERVICE_NAME));
            fail("should have thrown an exception");
        } catch (ServiceNotFoundException expected) {
            // expected
            assertEquals(SERVICE_NAME, expected.getServiceName());
        }
        assertFalse(serviceManager.isInitializeCalled());
        assertFalse(serviceManager.isDestroyCalled());
    }

    /**
     * Test the registration and unregistration.
     * Strategy:
     * <ul><li>
     * Register a service
     * </li><li>
     * Verify the service was registered and callbacks were made
     * <ul><li>
     * Unregister the service
     * </li><li>
     * Verify the service was unregistered and callbacks were made
     * </li></ul>
     *
     * @throws Exception if there is a failure
     */
    public void testRegisterUnregister() throws Exception {
        register();
        unregister();
    }

    /**
     * Tests the destroy method.
     * Strategy:
     * <ul><li>
     * Register a service
     * </li><li>
     * Verify the service was registered and callbacks were made
     * <ul><li>
     * Destroy the registry
     * </li><li>
     * Verify the service was stopped and callbacks were made
     * </li></ul>
     *
     * @throws Exception if there is a failure
     */
    public void testDestroy() throws Exception {
        register();
        destroy();
    }

    /**
     * Tests that an exception is thrown if an attempt is made to register.
     *
     * @throws Exception if there is a failure
     */
    public void testDoubleRegister() throws Exception {
        register();
        try {
            registry.registerService(SERVICE_NAME, SERVICE_FACTORY, CLASS_LOADER);
            fail("should have thrown an exception");
        } catch (ServiceAlreadyExistsException expected) {
            // expected
            assertEquals(SERVICE_NAME, expected.getServiceName());
        }
    }

    /**
     * Test that an attempt to unregister a service that is not registered throws an exception.
     *
     * @throws Exception if there is a failure
     */
    public void testUnregisterUnknown() throws Exception {
        try {
            registry.unregisterService(SERVICE_NAME, StopStrategies.SYNCHRONOUS);
        } catch (ServiceNotFoundException expected) {
            // expected
            assertEquals(SERVICE_NAME, expected.getServiceName());
        }
    }

    /**
     * Tests that when the initialize method throws an exception the service is not registered.
     *
     * @throws Exception if there is a failure
     */
    public void testRegisterException() throws Exception {
        register(new Exception("register exception"));
        register(new RuntimeException("register runtime exception"));
        register(new Error("register error"));
        register();
        unregister();
    }

    /**
     * Tests that when the destroy method throws an exception the service is not unregistered.
     *
     * @throws Exception if there is a failure
     */
    public void testUnregisterException() throws Exception {
        register();
        unregister(new UnsatisfiedConditionsException("destroy exception", SERVICE_NAME, Collections.EMPTY_SET));
        unregister(new IllegalServiceStateException("destroy exception", SERVICE_NAME));
        unregister(new RuntimeException("destroy exception"));
        unregister(new Error("destroy exception"));
        unregister();
    }

    /**
     * Tests that when the destroy and/or stop methods throw an exception during registry destroy, that destruction
     * continues and the exceptions are thrown in a single KernelErrorsError.
     *
     * @throws Exception if there is a failure
     */
    public void testDestroyException() throws Exception {
        register();
        destroy(new UnsatisfiedConditionsException("destroy exception", SERVICE_NAME, Collections.EMPTY_SET), null);
        register();
        destroy(new RuntimeException("destroy exception"), null);
        register();
        destroy(new Error("destroy exception"), null);
        register();
        destroy(new UnsatisfiedConditionsException("destroy exception", SERVICE_NAME, Collections.EMPTY_SET), new UnsatisfiedConditionsException("destroy exception", SERVICE_NAME, Collections.EMPTY_SET));
        register();
        destroy(new RuntimeException("destroy exception"), new UnsatisfiedConditionsException("destroy exception", SERVICE_NAME, Collections.EMPTY_SET));
        register();
        destroy(new Error("destroy exception"), new UnsatisfiedConditionsException("destroy exception", SERVICE_NAME, Collections.EMPTY_SET));
        register();
        destroy(null, new UnsatisfiedConditionsException("destroy exception", SERVICE_NAME, Collections.EMPTY_SET));
        register();
        destroy(new UnsatisfiedConditionsException("destroy exception", SERVICE_NAME, Collections.EMPTY_SET), new IllegalServiceStateException("destroy exception", SERVICE_NAME));
        register();
        destroy(new RuntimeException("destroy exception"), new IllegalServiceStateException("destroy exception", SERVICE_NAME));
        register();
        destroy(new Error("destroy exception"), new IllegalServiceStateException("destroy exception", SERVICE_NAME));
        register();
        destroy(null, new IllegalServiceStateException("destroy exception", SERVICE_NAME));
        register();
        destroy(new UnsatisfiedConditionsException("destroy exception", SERVICE_NAME, Collections.EMPTY_SET), new RuntimeException("destroy exception"));
        register();
        destroy(new RuntimeException("destroy exception"), new RuntimeException("destroy exception"));
        register();
        destroy(new Error("destroy exception"), new RuntimeException("destroy exception"));
        register();
        destroy(null, new RuntimeException("destroy exception"));
        register();
        destroy(new UnsatisfiedConditionsException("destroy exception", SERVICE_NAME, Collections.EMPTY_SET), new Error("destroy exception"));
        register();
        destroy(new RuntimeException("destroy exception"), new Error("destroy exception"));
        register();
        destroy(new Error("destroy exception"), new Error("destroy exception"));
        register();
        destroy(null, new Error("destroy exception"));
    }

    /**
     * Tests that when a service manager blocks during registration, that the registry blocks isRegistered and
     * getServiceManager calls until the registration completes.
     *
     * @throws Exception if there is a failure
     */
    public void testRegisterWaiting() throws Exception {
        registerWaiting(null);
    }

    /**
     * Tests that when a service manager blocks during registration and then throws an exception, that the registry
     * blocks isRegistered and getServiceManager calls until the registration completes, and then returns the correct
     * values for an unregistered service.
     *
     * @throws Exception if there is a failure
     */
    public void testRegisterWaitingException() throws Exception {
        registerWaiting(new Exception("register exception"));
        registerWaiting(new RuntimeException("register runtime exception"));
        registerWaiting(new Error("register error"));
    }

    /**
     * Tests that when a blocking service throws an exception during registration a nother service can wait be waiting
     * to take over the registration from the failed thread.
     *
     * @throws Exception if there is a failure
     */
    public void testDoubleRegisterWaiting() throws Exception {
        // start thread to attempt to register but throw an exception
        FutureTask registerFailTask = registerWaitingTask(new Exception("register exception"));

        // start thread to successfully register
        final CountDownLatch registerStartedSignal = new CountDownLatch(1);
        final MockServiceManager newServiceManager = new MockServiceManager();
        newServiceManager.setWait();
        FutureTask registerTask = new FutureTask(new Callable() {
            public Object call() throws Exception {
                registerStartedSignal.countDown();
                register(null, newServiceManager);
                return Boolean.TRUE;
            }
        });
        Thread registerThread = new Thread(registerTask, "registerTask");
        registerThread.setDaemon(true);
        registerThread.start();
        registerStartedSignal.await(TIMEOUT_DURATION, TIMEOUT_UNITS);

        // sleep a bit to assure that the register thread entered the registry code
        Thread.sleep(100);

        // verify all are not done
        assertFalse(registerFailTask.isDone());
        assertFalse(registerTask.isDone());

        // finish register fail, and verify it failed
        serviceManager.signalExit();
        assertEquals(Boolean.FALSE, registerFailTask.get(TIMEOUT_DURATION, TIMEOUT_UNITS));

        // verify success registration and verify itworked
        newServiceManager.signalExit();
        assertEquals(Boolean.TRUE, registerTask.get(TIMEOUT_DURATION, TIMEOUT_UNITS));
        assertTrue(registry.isRegistered(SERVICE_NAME));
        assertEquals(newServiceManager, registry.getServiceManager(SERVICE_NAME));
    }

    /**
     * Tests that when a service manager blocks during unregistration, that the registry blocks isRegistered and
     * getServiceManager calls until the unregistration completes.
     *
     * @throws Exception if there is a failure
     */
    public void testUnregisterWaiting() throws Exception {
        register();
        unregisterWaiting(null);
    }

    /**
     * Tests that when a service manager blocks during unregistration and then throws an exception, that the registry
     * blocks isRegistered and getServiceManager calls until the unregistration completes, and then returns the correct
     * values for an unregistered service.
     *
     * @throws Exception if there is a failure
     */
    public void testUnregisterWaitingException() throws Exception {
        register();
        unregisterWaiting(new UnsatisfiedConditionsException("destroy exception", SERVICE_NAME, Collections.EMPTY_SET));
        unregisterWaiting(new IllegalServiceStateException("destroy exception", SERVICE_NAME));
        unregisterWaiting(new RuntimeException("destroy exception"));
        unregisterWaiting(new Error("destroy exception"));
        unregisterWaiting(null);
    }

    /**
     * Tests that when a service manager blocks during destroy, that the registry does not block isRegistered and
     * getServiceManager calls, and then returns the correct values for an unregistered service.
     *
     * @throws Exception if there is a failure
     */
    public void testDestroyWaiting() throws Exception {
        register();

        // start thread to destroy and wait
        FutureTask destroyTask = destroyWaitingTask();

        // verify all are not done
        assertFalse(destroyTask.isDone());

        // verify that the service already appears to be unregistered
        assertFalse(registry.isRegistered(SERVICE_NAME));
        try {
            assertNull(registry.getServiceManager(SERVICE_NAME));
            fail("should have thrown an exception");
        } catch (ServiceNotFoundException expected) {
            // expected
            assertEquals(SERVICE_NAME, expected.getServiceName());
        }

        // finish register
        serviceManager.signalExit();

        // verify registration worked
        assertEquals(Boolean.TRUE, destroyTask.get(TIMEOUT_DURATION, TIMEOUT_UNITS));
        assertFalse(registry.isRegistered(SERVICE_NAME));
        try {
            assertNull(registry.getServiceManager(SERVICE_NAME));
            fail("should have thrown an exception");
        } catch (ServiceNotFoundException expected) {
            // expected
            assertEquals(SERVICE_NAME, expected.getServiceName());
        }
    }

    private void registerWaiting(Throwable throwable) throws Exception {
        // start thread to register and wait
        FutureTask registerTask = registerWaitingTask(throwable);

        // start thread to attempt getService
        FutureTask getServiceManagerTask = getServiceWaiting();

        // start thread to attempt isRegistered
        FutureTask isRegisteredTask = isRegisteredWaiting();

        // not necessary, but sleep a bit anyway
        Thread.sleep(100);

        // verify all are not done
        assertFalse(registerTask.isDone());
        assertFalse(getServiceManagerTask.isDone());
        assertFalse(isRegisteredTask.isDone());

        // finish register
        serviceManager.signalExit();

        if (throwable == null) {
            // verify registration worked
            assertEquals(Boolean.TRUE, registerTask.get(TIMEOUT_DURATION, TIMEOUT_UNITS));
            assertTrue(registry.isRegistered(SERVICE_NAME));
            assertEquals(serviceManager, registry.getServiceManager(SERVICE_NAME));

            // verify waiting isRegistered worked
            assertEquals(Boolean.TRUE, isRegisteredTask.get(TIMEOUT_DURATION, TIMEOUT_UNITS));

            // verify getServiceManager worked
            assertEquals(serviceManager, getServiceManagerTask.get(TIMEOUT_DURATION, TIMEOUT_UNITS));
        } else {
            // verify registration failed
            assertEquals(Boolean.FALSE, registerTask.get(TIMEOUT_DURATION, TIMEOUT_UNITS));
            assertFalse(registry.isRegistered(SERVICE_NAME));
            try {
                assertNull(registry.getServiceManager(SERVICE_NAME));
                fail("should have thrown an exception");
            } catch (ServiceNotFoundException expected) {
                // expected
                assertEquals(SERVICE_NAME, expected.getServiceName());
            }

            // verify waiting isRegistered worked
            assertEquals(Boolean.FALSE, isRegisteredTask.get(TIMEOUT_DURATION, TIMEOUT_UNITS));

            // verify getServiceManager worked
            try {
                getServiceManagerTask.get(TIMEOUT_DURATION, TIMEOUT_UNITS);
                fail("should have thrown an exception");
            } catch (ExecutionException e) {
                assertTrue(e.getCause() instanceof ServiceNotFoundException);
                ServiceNotFoundException serviceNotFoundException = (ServiceNotFoundException) e.getCause();
                assertSame(SERVICE_NAME, serviceNotFoundException.getServiceName());
            }
        }
    }

    private FutureTask registerWaitingTask(final Throwable throwable) throws InterruptedException {
        serviceManager.setWait();
        FutureTask registerTask = new FutureTask(new Callable() {
            public Object call() throws Exception {
                register(throwable);
                return Boolean.valueOf(throwable == null);
            }
        });
        Thread registerThread = new Thread(registerTask, throwable == null ? "registerTask" : "registerExceptionTask");
        registerThread.setDaemon(true);
        registerThread.start();

        // wait for register to block
        assertTrue(serviceManager.awaitEnterSignal());
        return registerTask;
    }

    private void unregisterWaiting(Throwable throwable) throws Exception {
        // start thread to unregister and wait
        FutureTask unregisterTask = unregisterWaitingTask(throwable);

        // start thread to attempt getService
        FutureTask getServiceManagerTask = getServiceWaiting();

        // start thread to attempt isRegistered
        FutureTask isRegisteredTask = isRegisteredWaiting();

        // not necessary, but sleep a bit anyway
        Thread.sleep(100);

        // verify all are not done
        assertFalse(unregisterTask.isDone());
        assertFalse(getServiceManagerTask.isDone());
        assertFalse(isRegisteredTask.isDone());

        // finish register
        serviceManager.signalExit();

        if (throwable == null) {
            // verify registration worked
            assertEquals(Boolean.TRUE, unregisterTask.get(TIMEOUT_DURATION, TIMEOUT_UNITS));
            assertFalse(registry.isRegistered(SERVICE_NAME));
            try {
                assertNull(registry.getServiceManager(SERVICE_NAME));
                fail("should have thrown an exception");
            } catch (ServiceNotFoundException expected) {
                // expected
                assertEquals(SERVICE_NAME, expected.getServiceName());
            }

            // verify waiting isRegistered worked
            assertEquals(Boolean.FALSE, isRegisteredTask.get(TIMEOUT_DURATION, TIMEOUT_UNITS));

            // verify getServiceManager worked
            try {
                getServiceManagerTask.get(TIMEOUT_DURATION, TIMEOUT_UNITS);
                fail("should have thrown an exception");
            } catch (ExecutionException e) {
                assertTrue(e.getCause() instanceof ServiceNotFoundException);
                ServiceNotFoundException serviceNotFoundException = (ServiceNotFoundException) e.getCause();
                assertSame(SERVICE_NAME, serviceNotFoundException.getServiceName());
            }
        } else {
            // verify unregistration failed
            assertEquals(Boolean.FALSE, unregisterTask.get(TIMEOUT_DURATION, TIMEOUT_UNITS));
            assertTrue(registry.isRegistered(SERVICE_NAME));
            assertEquals(serviceManager, registry.getServiceManager(SERVICE_NAME));

            // verify waiting isRegistered worked
            assertEquals(Boolean.TRUE, isRegisteredTask.get(TIMEOUT_DURATION, TIMEOUT_UNITS));

            // verify getServiceManager worked
            assertEquals(serviceManager, getServiceManagerTask.get(TIMEOUT_DURATION, TIMEOUT_UNITS));
        }
    }

    private FutureTask unregisterWaitingTask(final Throwable throwable) throws InterruptedException {
        serviceManager.setWait();
        FutureTask unregisterTask = new FutureTask(new Callable() {
            public Object call() throws Exception {
                unregister(throwable);
                return Boolean.valueOf(throwable == null);
            }
        });
        Thread unregisterThread = new Thread(unregisterTask, throwable == null ? "unregisterTask" : "unregisterExceptionTask");
        unregisterThread.setDaemon(true);
        unregisterThread.start();

        // wait for register to block
        assertTrue(serviceManager.awaitEnterSignal());
        return unregisterTask;
    }

    private FutureTask destroyWaitingTask() throws InterruptedException {
        serviceManager.setWait();
        FutureTask unregisterTask = new FutureTask(new Callable() {
            public Object call() throws Exception {
                destroy();
                return Boolean.TRUE;
            }
        });
        Thread destroyThread = new Thread(unregisterTask, "destroyTask");
        destroyThread.setDaemon(true);
        destroyThread.start();

        // wait for register to block
        assertTrue(serviceManager.awaitEnterSignal());
        return unregisterTask;
    }

    private FutureTask getServiceWaiting() throws InterruptedException {
        final CountDownLatch getServiceManagerSignal = new CountDownLatch(1);
        FutureTask getServiceManagerTask = new FutureTask(new Callable() {
            public Object call() throws Exception {
                getServiceManagerSignal.countDown();
                return registry.getServiceManager(SERVICE_NAME);
            }
        });
        Thread getServiceManagerThread = new Thread(getServiceManagerTask, "getServiceManagerTask");
        getServiceManagerThread.setDaemon(true);
        getServiceManagerThread.start();

        // wait for thread started
        getServiceManagerSignal.await(TIMEOUT_DURATION, TIMEOUT_UNITS);
        return getServiceManagerTask;
    }

    private FutureTask isRegisteredWaiting() throws InterruptedException {
        final CountDownLatch isRegisteredSignal = new CountDownLatch(1);
        FutureTask isRegisteredTask = new FutureTask(new Callable() {
            public Object call() throws Exception {
                isRegisteredSignal.countDown();
                return Boolean.valueOf(registry.isRegistered(SERVICE_NAME));
            }
        });
        Thread isRegisteredThread = new Thread(isRegisteredTask, "isRegisteredTask");
        isRegisteredThread.setDaemon(true);
        isRegisteredThread.start();

        // wait for thread started
        isRegisteredSignal.await(TIMEOUT_DURATION, TIMEOUT_UNITS);
        return isRegisteredTask;
    }

    private void register() throws Exception {
        register(null, serviceManager);
    }

    private void register(Throwable throwable) throws Exception {
        register(throwable, serviceManager);
    }

    private void register(Throwable throwable, MockServiceManager serviceManager) throws Exception {
        serviceManager.reset();
        serviceManager.setInitializeException(throwable);
        serviceManagerFactory.addServiceManager(serviceManager);
        try {
            registry.registerService(SERVICE_NAME, SERVICE_FACTORY, CLASS_LOADER);
            assertNull(throwable);
        } catch (ServiceRegistrationException expected) {
            // expected
            assertSame(throwable, expected.getCause());
            assertSame(SERVICE_NAME, expected.getServiceName());
        }

        if (throwable == null) {
            assertTrue(registry.isRegistered(SERVICE_NAME));
            assertEquals(serviceManager, registry.getServiceManager(SERVICE_NAME));
        } else {
            assertFalse(registry.isRegistered(SERVICE_NAME));
            try {
                assertNull(registry.getServiceManager(SERVICE_NAME));
                fail("should have thrown an exception");
            } catch (ServiceNotFoundException expected) {
                // expected
                assertEquals(SERVICE_NAME, expected.getServiceName());
            }
        }
        assertTrue(serviceManager.isInitializeCalled());
        assertFalse(serviceManager.isDestroyCalled());
    }

    private void unregister() throws ServiceNotFoundException {
        unregister(null);
    }

    private void unregister(Throwable throwable) throws ServiceNotFoundException {
        serviceManager.reset();
        serviceManager.setDestroyException(throwable);
        try {
            registry.unregisterService(SERVICE_NAME, StopStrategies.SYNCHRONOUS);
            assertNull(throwable);
        } catch (ServiceRegistrationException expected) {
            // expected
            assertSame(SERVICE_NAME, expected.getServiceName());
            assertSame(throwable, expected.getCause());
        }

        if (throwable == null) {
            assertFalse(registry.isRegistered(SERVICE_NAME));
            try {
                assertNull(registry.getServiceManager(SERVICE_NAME));
                fail("should have thrown an exception");
            } catch (ServiceNotFoundException expected) {
                // expected
                assertEquals(SERVICE_NAME, expected.getServiceName());
            }
        } else {
            assertTrue(registry.isRegistered(SERVICE_NAME));
            assertEquals(serviceManager, registry.getServiceManager(SERVICE_NAME));
        }
        assertFalse(serviceManager.isInitializeCalled());
        assertTrue(serviceManager.isDestroyCalled());
    }

    private void destroy() {
        destroy(null, null);
    }

    private void destroy(Throwable stopException, Throwable destroyException) {
        serviceManager.reset();
        serviceManager.setStopException(stopException);
        serviceManager.setDestroyException(destroyException);

        try {
            registry.destroy();
            assertNull(stopException);
            assertNull(destroyException);
        } catch (KernelErrorsError kernelErrorsError) {
            List errors = new ArrayList(kernelErrorsError.getErrors());
            if (stopException != null) {
                assertTrue(errors.size() >= 3);
                assertTrue(errors.get(0) instanceof AssertionError);
                assertSame(stopException, ((AssertionError) errors.get(0)).getCause());
                assertTrue(errors.get(1) instanceof AssertionError);
                assertSame(stopException, ((AssertionError) errors.get(1)).getCause());
                assertTrue(errors.get(2) instanceof AssertionError);
                assertSame(stopException, ((AssertionError) errors.get(2)).getCause());
                errors = errors.subList(3, errors.size());
            }

            if (destroyException != null) {
                assertEquals(1, errors.size());
                assertTrue(errors.get(0) instanceof AssertionError);
                assertSame(destroyException, ((AssertionError) errors.get(0)).getCause());
                errors = Collections.EMPTY_LIST;
            }

            assertEquals(Collections.EMPTY_LIST, errors);
        }

        assertFalse(registry.isRegistered(SERVICE_NAME));
        try {
            assertNull(registry.getServiceManager(SERVICE_NAME));
            fail("should have thrown an exception");
        } catch (ServiceNotFoundException expected) {
            // expected
            assertEquals(SERVICE_NAME, expected.getServiceName());
        }
        assertFalse(serviceManager.isInitializeCalled());
        assertTrue(serviceManager.isStopCalled());
        assertTrue(serviceManager.isDestroyCalled());
    }

    private static class MockServiceManagerFactory extends ServiceManagerFactory {
        private final LinkedList serviceManagers = new LinkedList();

        private MockServiceManagerFactory() {
            super(null, null, null, 0, null);
        }

        public ServiceManager createServiceManager(ServiceName serviceName, ServiceFactory serviceFactory, ClassLoader classLoader) {
            assertEquals(SERVICE_NAME, serviceName);
            assertEquals(SERVICE_FACTORY, serviceFactory);
            assertEquals(CLASS_LOADER, classLoader);
            synchronized (serviceManagers) {
                return (ServiceManager) serviceManagers.removeFirst();
            }
        }

        public void addServiceManager(ServiceManager serviceManager) {
            synchronized (serviceManagers) {
                serviceManagers.add(serviceManager);
            }
        }
    }

    private static class MockServiceManager extends ServiceManager {
        private boolean initializeCalled;
        private boolean destroyCalled;
        private boolean stopCalled;
        private Throwable initializeException;
        private Throwable destroyException;
        private Throwable stopException;
        private CountDownLatch enterWaiting = new CountDownLatch(1);
        private CountDownLatch exitWaiting = new CountDownLatch(0);


        private MockServiceManager() {
            super(null, null, null, null, null, null, 0, null);
        }

        private synchronized void reset() {
            initializeCalled = false;
            destroyCalled = false;
            stopCalled = false;
            initializeException = null;
            destroyException = null;
            stopException = null;
        }

        public void initialize() throws IllegalServiceStateException, UnsatisfiedConditionsException, Exception {
            synchronized (this) {
                assertFalse(initializeCalled);
                initializeCalled = true;
            }

            signalEnter();
            awaitExitSignal();

            synchronized (this) {
                if (initializeException instanceof Exception) {
                    throw (Exception) initializeException;
                } else if (initializeException instanceof Error) {
                    throw (Error) initializeException;
                }
            }
        }

        public void destroy(StopStrategy stopStrategy) throws IllegalServiceStateException, UnsatisfiedConditionsException {
            synchronized (this) {
                assertFalse(destroyCalled);
                destroyCalled = true;
            }

            try {
                signalEnter();
                awaitExitSignal();
            } catch (InterruptedException e) {
                fail("destroyCondition.await() threw an exception");
            }

            synchronized (this) {
                if (destroyException instanceof UnsatisfiedConditionsException) {
                    throw (UnsatisfiedConditionsException) destroyException;
                } else if (destroyException instanceof IllegalServiceStateException) {
                    throw (IllegalServiceStateException) destroyException;
                } else if (destroyException instanceof RuntimeException) {
                    throw (RuntimeException) destroyException;
                } else if (destroyException instanceof Error) {
                    throw (Error) destroyException;
                }
            }
        }

        public synchronized boolean stop(StopStrategy stopStrategy) throws UnsatisfiedConditionsException {
            stopCalled = true;

            if (stopException instanceof UnsatisfiedConditionsException) {
                throw (UnsatisfiedConditionsException) stopException;
            } else if (stopException instanceof RuntimeException) {
                throw (RuntimeException) stopException;
            } else if (stopException instanceof Error) {
                throw (Error) stopException;
            }
            return true;
        }

        public synchronized boolean isInitializeCalled() {
            return initializeCalled;
        }

        public synchronized boolean isDestroyCalled() {
            return destroyCalled;
        }

        public synchronized boolean isStopCalled() {
            return stopCalled;
        }

        public synchronized void setInitializeException(Throwable initializeException) {
            this.initializeException = initializeException;
        }

        public synchronized void setDestroyException(Throwable destroyException) {
            this.destroyException = destroyException;
        }

        public synchronized void setStopException(Throwable stopException) {
            this.stopException = stopException;
        }

        public boolean awaitEnterSignal() throws InterruptedException {
            CountDownLatch signal;
            synchronized (this) {
                signal = enterWaiting;
            }
            boolean worked = signal.await(TIMEOUT_DURATION, TIMEOUT_UNITS);
            return worked;
        }

        private void signalEnter() {
            CountDownLatch signal;
            synchronized (this) {
                signal = enterWaiting;
            }
            signal.countDown();
        }

        public synchronized void setWait() {
            exitWaiting = new CountDownLatch(1);
            enterWaiting = new CountDownLatch(1);
        }

        public void signalExit() {
            CountDownLatch signal;
            synchronized (this) {
                signal = exitWaiting;
            }
            signal.countDown();
        }

        private void awaitExitSignal() throws InterruptedException {
            CountDownLatch signal;
            synchronized (this) {
                signal = exitWaiting;
            }
            signal.await(TIMEOUT_DURATION, TIMEOUT_UNITS);
        }
    }
}
