FELIX-2647 First checkin of the Apache Felix Coordinator Service implementation

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1006352 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/coordinator/DEPENDENCIES b/coordinator/DEPENDENCIES
new file mode 100644
index 0000000..a29f455
--- /dev/null
+++ b/coordinator/DEPENDENCIES
@@ -0,0 +1,30 @@
+Apache Felix Coordinator Service
+Copyright 2010 The Apache Software Foundation
+
+
+I. Included Software
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+Licensed under the Apache License 2.0.
+
+This product includes software developed at
+The OSGi Alliance (http://www.osgi.org/).
+Copyright (c) OSGi Alliance (2000, 2010).
+Licensed under the Apache License 2.0. 
+
+
+II. Used Software
+
+This product uses software developed at
+The Apache Software Foundation (http://www.apache.org/).
+Licensed under the Apache License 2.0.
+
+This product uses software developed at
+The OSGi Alliance (http://www.osgi.org/).
+Copyright (c) OSGi Alliance (2000, 2010).
+Licensed under the Apache License 2.0. 
+
+
+III. License Summary
+- Apache License 2.0
diff --git a/coordinator/LICENSE b/coordinator/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/coordinator/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   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.
diff --git a/coordinator/NOTICE b/coordinator/NOTICE
new file mode 100644
index 0000000..3e0135b
--- /dev/null
+++ b/coordinator/NOTICE
@@ -0,0 +1,11 @@
+Apache Felix Coordinator Service
+Copyright 2010 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+Licensed under the Apache License 2.0.
+
+This product includes software developed at
+The OSGi Alliance (http://www.osgi.org/).
+Copyright (c) OSGi Alliance (2000, 2010).
+Licensed under the Apache License 2.0. 
diff --git a/coordinator/pom.xml b/coordinator/pom.xml
new file mode 100644
index 0000000..365daff
--- /dev/null
+++ b/coordinator/pom.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>felix-parent</artifactId>
+        <version>1.2.0</version>
+        <relativePath>../pom/pom.xml</relativePath>
+    </parent>
+
+    <artifactId>org.apache.felix.coordinator</artifactId>
+    <packaging>bundle</packaging>
+
+    <name>Apache Felix Coordinator Service</name>
+    <description>
+        Implementation of the OSGi Coordinator Service Specification 1.0
+        (Based on OSGi R 4.3 Draft 2 (31 Aug. 2010))
+    </description>
+    <version>0.0.1-SNAPSHOT</version>
+
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>5</source>
+                    <target>5</target>
+                </configuration>
+            </plugin>
+            <plugin>
+                <artifactId>maven-javadoc-plugin</artifactId>
+                <configuration>
+                    <tags>
+                        <tag>
+                            <name>ThreadSafe</name>
+                            <placement>a</placement>
+                            <head>ThreadSafe</head>
+                        </tag>
+                        <tag>
+                            <name>Provisional</name>
+                            <placement>a</placement>
+                            <head>
+                                This is provisional API derived from OSGi R4.3 DRAFT 2 specification. This API is provided for testing purposes and gaining experience. As such this API is subject to change and will be removed once the OSGi R4.3 specification is finalized.
+                            </head>
+                        </tag>
+                    </tags>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <version>2.0.1</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Bundle-Category>osgi</Bundle-Category>
+                        <Bundle-SymbolicName>
+                            ${artifactId}
+                        </Bundle-SymbolicName>
+                        <Bundle-DocURL>
+                            http://felix.apache.org/site/apache-felix-coordination-service.html
+                        </Bundle-DocURL>
+                        <Export-Package>
+                            org.apache.felix.jmx.service.coordination;
+                            org.apache.felix.service.coordination;
+                                version=1.0;
+                                mandatory:="status"; status="provisional"
+                        </Export-Package>
+                        <Private-Package>
+                            org.apache.felix.coordination.impl.*
+                        </Private-Package>
+                        <Bundle-Activator>
+                            org.apache.felix.coordination.impl.Activator
+                        </Bundle-Activator>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <version>4.2.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+            <version>4.2.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.enterprise</artifactId>
+            <version>4.2.0</version>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/coordinator/src/main/java/org/apache/felix/coordination/impl/Activator.java b/coordinator/src/main/java/org/apache/felix/coordination/impl/Activator.java
new file mode 100644
index 0000000..c84721a
--- /dev/null
+++ b/coordinator/src/main/java/org/apache/felix/coordination/impl/Activator.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.felix.coordination.impl;
+
+import java.util.Hashtable;
+
+import org.apache.felix.service.coordination.Coordinator;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceRegistration;
+
+@SuppressWarnings("deprecation")
+public class Activator implements BundleActivator {
+
+    private CoordinationMgr mgr;
+
+    private ServiceRegistration coordinatorService;
+
+    public void start(BundleContext context) throws Exception {
+        mgr = new CoordinationMgr();
+
+        ServiceFactory factory = new CoordinatorFactory(mgr);
+        Hashtable<String, String> props = new Hashtable<String, String>();
+        props.put(Constants.SERVICE_DESCRIPTION,
+            "Coordinator Service Implementation");
+        props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
+        coordinatorService = context.registerService(
+            Coordinator.class.getName(), factory, props);
+    }
+
+    public void stop(BundleContext context) throws Exception {
+        if (coordinatorService != null) {
+            coordinatorService.unregister();
+            coordinatorService = null;
+        }
+
+        mgr.cleanUp();
+    }
+
+    static final class CoordinatorFactory implements ServiceFactory {
+
+        private final CoordinationMgr mgr;
+
+        CoordinatorFactory(final CoordinationMgr mgr) {
+            this.mgr = mgr;
+        }
+
+        public Object getService(Bundle bundle, ServiceRegistration registration) {
+            return new CoordinatorImpl(bundle, mgr);
+        }
+
+        public void ungetService(Bundle bundle,
+                ServiceRegistration registration, Object service) {
+            // nothing to do
+        }
+
+    }
+}
diff --git a/coordinator/src/main/java/org/apache/felix/coordination/impl/CoordinationImpl.java b/coordinator/src/main/java/org/apache/felix/coordination/impl/CoordinationImpl.java
new file mode 100644
index 0000000..f8ac3b0
--- /dev/null
+++ b/coordinator/src/main/java/org/apache/felix/coordination/impl/CoordinationImpl.java
@@ -0,0 +1,166 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.felix.coordination.impl;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.felix.service.coordination.Coordination;
+import org.apache.felix.service.coordination.Participant;
+
+@SuppressWarnings("deprecation")
+public class CoordinationImpl implements Coordination {
+
+    private enum State {
+        /** Active */
+        ACTIVE,
+
+        /** Coordination termination started */
+        TERMINATING,
+
+        /** Coordination completed */
+        TERMINATED,
+
+        /** Coordination failed */
+        FAILED;
+    }
+
+    private final long id;
+
+    private final String name;
+
+    // TODO: timeout must be enforced
+    private long timeOutInMs;
+
+    private State state;
+
+    private boolean mustFail;
+
+    private boolean timeout;
+
+    private ArrayList<Participant> participants;
+
+    private HashMap<Class<?>, Object> variables;
+
+    public CoordinationImpl(final long id, final String name) {
+        this.id = id;
+        this.name = name;
+        this.state = State.ACTIVE;
+        this.participants = new ArrayList<Participant>();
+        this.variables = new HashMap<Class<?>, Object>();
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    long getId() {
+        return this.id;
+    }
+
+    void mustFail() {
+        this.mustFail = true;
+    }
+
+    void timeout() {
+        this.timeout = true;
+    }
+
+    long getTimeOut() {
+        return this.timeOutInMs;
+    }
+
+    public int end() throws IllegalStateException {
+        if (state == State.ACTIVE) {
+            int reason = OK;
+            if (mustFail || timeout) {
+                fail(new Exception());
+                reason = mustFail ? FAILED : TIMEOUT;
+            } else {
+                state = State.TERMINATING;
+                for (Participant part : participants) {
+                    try {
+                        part.ended(this);
+                    } catch (Exception e) {
+                        // TODO: log
+                        reason = PARTIALLY_ENDED;
+                    }
+                }
+                state = State.TERMINATED;
+            }
+            return reason;
+        }
+
+        // already terminated
+        throw new IllegalStateException();
+    }
+
+    public boolean fail(Throwable reason) {
+        if (state == State.ACTIVE) {
+            state = State.TERMINATING;
+            for (Participant part : participants) {
+                try {
+                    part.failed(this);
+                } catch (Exception e) {
+                    // TODO: log
+                }
+            }
+            state = State.FAILED;
+            return true;
+        }
+        return false;
+    }
+
+    public boolean terminate() {
+        if (state == State.ACTIVE) {
+            end();
+            return true;
+        }
+        return false;
+    }
+
+    public boolean isFailed() {
+        return state == State.FAILED;
+    }
+
+    public void addTimeout(long timeOutInMs) {
+        this.timeOutInMs = timeOutInMs;
+    }
+
+    public boolean participate(Participant p) {
+        if (state == State.ACTIVE) {
+            if (!participants.contains(p)) {
+                participants.add(p);
+            }
+            return true;
+        }
+        return false;
+    }
+
+    public Collection<Participant> getParticipants() {
+        return new ArrayList<Participant>(participants);
+    }
+
+    public Map<Class<?>, ?> getVariables() {
+        return variables;
+    }
+
+}
diff --git a/coordinator/src/main/java/org/apache/felix/coordination/impl/CoordinationMgr.java b/coordinator/src/main/java/org/apache/felix/coordination/impl/CoordinationMgr.java
new file mode 100644
index 0000000..77f3e90
--- /dev/null
+++ b/coordinator/src/main/java/org/apache/felix/coordination/impl/CoordinationMgr.java
@@ -0,0 +1,196 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.felix.coordination.impl;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Stack;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.regex.Pattern;
+
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.OpenDataException;
+import javax.management.openmbean.TabularData;
+import javax.management.openmbean.TabularDataSupport;
+
+import org.apache.felix.jmx.service.coordination.CoordinatorMBean;
+import org.apache.felix.service.coordination.Coordination;
+import org.apache.felix.service.coordination.CoordinationException;
+import org.apache.felix.service.coordination.Participant;
+
+@SuppressWarnings("deprecation")
+public class CoordinationMgr implements CoordinatorMBean {
+
+    private ThreadLocal<Stack<Coordination>> threadStacks;
+
+    private final AtomicLong ctr;
+
+    private final Map<Long, CoordinationImpl> coordinations;
+
+    CoordinationMgr() {
+        ctr = new AtomicLong(-1);
+        coordinations = new HashMap<Long, CoordinationImpl>();
+    }
+
+    void unregister(final CoordinationImpl c) {
+        coordinations.remove(c.getId());
+        Stack<Coordination> stack = threadStacks.get();
+        if (stack != null) {
+            stack.remove(c);
+        }
+    }
+
+    void cleanUp() {
+        final Exception reason = new Exception();
+        for (Coordination c : coordinations.values()) {
+            c.fail(reason);
+        }
+        coordinations.clear();
+    }
+
+    public Coordination create(String name) {
+        long id = ctr.incrementAndGet();
+        CoordinationImpl c = new CoordinationImpl(id, name);
+        coordinations.put(id, c);
+        return c;
+    }
+
+    public Coordination begin(String name) {
+        return push(create(name));
+    }
+
+    public Coordination push(Coordination c) {
+        Stack<Coordination> stack = threadStacks.get();
+        if (stack == null) {
+            stack = new Stack<Coordination>();
+            threadStacks.set(stack);
+        }
+        return stack.push(c);
+    }
+
+    public Coordination pop() {
+        Stack<Coordination> stack = threadStacks.get();
+        if (stack != null && !stack.isEmpty()) {
+            return stack.pop();
+        }
+        return null;
+    }
+
+    public Coordination getCurrentCoordination() {
+        Stack<Coordination> stack = threadStacks.get();
+        if (stack != null && !stack.isEmpty()) {
+            return stack.peek();
+        }
+        return null;
+    }
+
+    public boolean alwaysFail(Throwable reason) {
+        CoordinationImpl current = (CoordinationImpl) getCurrentCoordination();
+        if (current != null) {
+            current.mustFail();
+            return true;
+        }
+        return false;
+    }
+
+    public Collection<Coordination> getCoordinations() {
+        ArrayList<Coordination> result = new ArrayList<Coordination>();
+        Stack<Coordination> stack = threadStacks.get();
+        if (stack != null) {
+            result.addAll(stack);
+        }
+        return result;
+    }
+
+    public boolean participate(Participant participant)
+            throws CoordinationException {
+        // TODO: check for multi-pariticipation and block
+        Coordination current = getCurrentCoordination();
+        if (current != null) {
+            current.participate(participant);
+            return true;
+        }
+        return false;
+    }
+
+    public Coordination participateOrBegin(Participant ifActive) {
+        // TODO: check for multi-pariticipation and block
+        Coordination current = getCurrentCoordination();
+        if (current == null) {
+            current = begin("implicit");
+        }
+        current.participate(ifActive);
+        return current;
+    }
+
+    // ---------- CoordinatorMBean interface
+
+    public TabularData listCoordinations(String regexFilter) {
+        Pattern p = Pattern.compile(regexFilter);
+        TabularData td = new TabularDataSupport(COORDINATIONS_TYPE);
+        for (CoordinationImpl c : coordinations.values()) {
+            if (p.matcher(c.getName()).matches()) {
+                try {
+                    td.put(fromCoordination(c));
+                } catch (OpenDataException e) {
+                    // TODO: log
+                }
+            }
+        }
+        return td;
+    }
+
+    public CompositeData getCoordination(long id) throws IOException {
+        CoordinationImpl c = coordinations.get(id);
+        if (c != null) {
+            try {
+                return fromCoordination(c);
+            } catch (OpenDataException e) {
+                throw new IOException(e.toString());
+            }
+        }
+        throw new IOException("No such Coordination " + id);
+    }
+
+    public boolean fail(long id, String reason) {
+        Coordination c = coordinations.get(id);
+        if (c != null) {
+            return c.fail(new Exception(reason));
+        }
+        return false;
+    }
+
+    public void addTimeout(long id, long timeout) {
+        Coordination c = coordinations.get(id);
+        if (c != null) {
+            c.addTimeout(timeout);
+        }
+    }
+
+    private CompositeData fromCoordination(final CoordinationImpl c)
+            throws OpenDataException {
+        return new CompositeDataSupport(COORDINATION_TYPE, new String[] { ID,
+            NAME, TIMEOUT }, new Object[] { c.getId(), c.getName(),
+            c.getTimeOut() });
+    }
+}
diff --git a/coordinator/src/main/java/org/apache/felix/coordination/impl/CoordinatorImpl.java b/coordinator/src/main/java/org/apache/felix/coordination/impl/CoordinatorImpl.java
new file mode 100644
index 0000000..dd5f5c0
--- /dev/null
+++ b/coordinator/src/main/java/org/apache/felix/coordination/impl/CoordinatorImpl.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.felix.coordination.impl;
+
+import java.util.Collection;
+import org.apache.felix.service.coordination.Coordination;
+import org.apache.felix.service.coordination.CoordinationException;
+import org.apache.felix.service.coordination.Coordinator;
+import org.apache.felix.service.coordination.Participant;
+import org.osgi.framework.Bundle;
+
+@SuppressWarnings("deprecation")
+public class CoordinatorImpl implements Coordinator {
+
+    private final Bundle owner;
+
+    private final CoordinationMgr mgr;
+
+    CoordinatorImpl(final Bundle owner, final CoordinationMgr mgr) {
+        this.owner = owner;
+        this.mgr = mgr;
+    }
+
+    public Coordination create(String name) {
+        // TODO: check permission
+        return mgr.create(name);
+    }
+
+    void unregister(final CoordinationImpl c) {
+        // TODO: check permission
+        mgr.unregister(c);
+    }
+
+    public Coordination begin(String name) {
+        // TODO: check permission
+        return mgr.begin(name);
+    }
+
+    public Coordination push(Coordination c) {
+        // TODO: check permission
+        return mgr.push(c);
+    }
+
+    public Coordination pop() {
+        // TODO: check permission
+        return mgr.pop();
+    }
+
+    public Coordination getCurrentCoordination() {
+        // TODO: check permission
+        return mgr.getCurrentCoordination();
+    }
+
+    public boolean alwaysFail(Throwable reason) {
+        // TODO: check permission
+        return mgr.alwaysFail(reason);
+    }
+
+    public Collection<Coordination> getCoordinations() {
+        // TODO: check permission
+        return mgr.getCoordinations();
+    }
+
+    public boolean participate(Participant participant)
+            throws CoordinationException {
+        // TODO: check permission
+        return mgr.participate(participant);
+    }
+
+    public Coordination participateOrBegin(Participant ifActive) {
+        // TODO: check permission
+        return mgr.participateOrBegin(ifActive);
+    }
+
+}
diff --git a/coordinator/src/main/java/org/apache/felix/jmx/service/coordination/CoordinatorMBean.java b/coordinator/src/main/java/org/apache/felix/jmx/service/coordination/CoordinatorMBean.java
new file mode 100644
index 0000000..4b4a616
--- /dev/null
+++ b/coordinator/src/main/java/org/apache/felix/jmx/service/coordination/CoordinatorMBean.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
+ *
+ * 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.apache.felix.jmx.service.coordination;
+
+import java.io.IOException;
+
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.SimpleType;
+import javax.management.openmbean.TabularData;
+import javax.management.openmbean.TabularType;
+
+import org.osgi.jmx.Item;
+
+/**
+ * This MBean provides the management interface to the OSGi Coordinator Service
+ *
+ * @ThreadSafe
+ * @Provisional
+ */
+@Deprecated
+public interface CoordinatorMBean {
+
+    /**
+     * User Admin MBean object name.
+     */
+    public static final String OBJECTNAME = "osgi.compendium:service=coordinator,version=1.0";
+
+    /**
+     * The key NAME, used in NAME_ITEM.
+     */
+    public static final String NAME = "Name";
+
+    /**
+     * The item for the user name for an authorization object. The key is NAME
+     * and the type is SimpleType.STRING.
+     */
+    public static final org.osgi.jmx.Item NAME_ITEM = new Item(NAME, null,
+        SimpleType.STRING, (String[]) null);
+
+    /**
+     * The key ID, used in ID_ITEM.
+     */
+    public static final String ID = "Id";
+
+    /**
+     * The item for the id of an Coordination object. The key is ID and the type
+     * is SimpleType.LONG. The id must be generated by the Mbean and map to a
+     * unique Coordination (which should no be pinned in memory because of
+     * this).
+     */
+    public static final org.osgi.jmx.Item ID_ITEM = new Item(ID, null,
+        SimpleType.LONG, (String[]) null);
+
+    /**
+     * The key TIMEOUT, used in TIMEOUT_ITEM.
+     */
+    public static final String TIMEOUT = "Timeout";
+
+    /**
+     * The item for the id of an Coordination object. The key is TIMEOUT and the
+     * type is SimpleType.LONG.
+     */
+    public static final org.osgi.jmx.Item TIMEOUT_ITEM = new Item(TIMEOUT,
+        null, SimpleType.LONG, (String[]) null);
+
+    /**
+     * The key COORDINATION, used in COORDINATION_TYPE
+     */
+    public static final String COORDINATION = "Coordination";
+
+    /**
+     * Interface Coordination
+     */
+    public static final CompositeType COORDINATION_TYPE = Item.compositeType(
+        "", null, ID_ITEM, NAME_ITEM, TIMEOUT_ITEM);
+
+    /**
+     * The key COORDINATIONS, used in COORDINATIONS_TYPE
+     * <p>
+     * fmeschbe note: This constant is added because it is needed for the
+     * {@link #COORDINATIONS_TYPE} definition
+     */
+    public static final String COORDINATIONS = "Coordinations";
+
+    /**
+     * Defines a list of COORDINATION_TYPE
+     * <p>
+     * fmeschbe note: The draft 2 spec defines this to be ArrayType but to
+     * use it for {@link #listCoordinations(String)} this constant must
+     * be a <code>TabularType</code>.
+     */
+    public static final TabularType COORDINATIONS_TYPE = Item.tabularType(
+        COORDINATIONS, null, COORDINATION_TYPE, ID, NAME, TIMEOUT);
+
+    /**
+     * List the current coordinations. The Composite Data is typed by
+     * COORDINATIONS_TYPE.
+     *
+     * @param regexFilter a regular expression filter on the coordination name
+     * @return the Coordinations typed by COORDINATIONS_TYPE.
+     * @throws IOException if the operation fails
+     */
+    TabularData listCoordinations(String regexFilter) throws IOException;
+
+    /**
+     * Get a Coordination. The Composite Data is typed by COORDINATION_TYPE.
+     *
+     * @param id The id of a Coordination
+     * @return the Coordinations typed by COORDINATION_TYPE.
+     * @throws IOException if the operation fails
+     */
+    CompositeData getCoordination(long id) throws IOException;
+
+    /**
+     * Fail a Coordination.
+     *
+     * @param id The id of the coordination to be failed.
+     * @param reason The reason the coordination should be failed. The
+     *            implementation of the MBean should create a
+     *            Throwable/Exception with this reason in order to fail the
+     *            specified Coordination
+     * @return true if the coordination was failed by this call, otherwise
+     *         false.
+     * @throws IOException
+     * @see Coordination#fail(Throwable)
+     */
+    boolean fail(long id, String reason) throws IOException;
+
+    /**
+     * Set/Change the timeout of a Coordination.
+     *
+     * @param id The id of the Coordination
+     * @param timeout The nr of milliseconds for the next timeout.
+     * @throws IOException
+     */
+    void addTimeout(long id, long timeout) throws IOException;
+}
diff --git a/coordinator/src/main/java/org/apache/felix/jmx/service/coordination/package-info.java b/coordinator/src/main/java/org/apache/felix/jmx/service/coordination/package-info.java
new file mode 100644
index 0000000..5989a55
--- /dev/null
+++ b/coordinator/src/main/java/org/apache/felix/jmx/service/coordination/package-info.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
+ *
+ * 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.
+ */
+/**
+ * OSGi JMX Coordination Package Version 1.0.
+ * <p>
+ * Bundles wishing to use this package must list the package in the
+ * Import-Package header of the bundle's manifest.
+ * <p>
+ * This package has two types of users: the consumers that use the API in this
+ * package and the providers that implement the API in this package.
+ * <p>
+ * Example import for consumers using the API in this package:
+ * <blockquote>
+ * <code>Import-Package: org.apache.felix.jmx.service.coordination; version="[1.0,2.0)"; status="provisional"</code>
+ * </blockquote>
+ * <p>
+ * Example import for providers implementing the API in this package:
+ * <blockquote>
+ * <code>Import-Package: org.apache.felix.jmx.service.coordination; version="[1.0,1.1)"; status="provisional"</code>
+ * </blockquote>
+ *
+ * @Provisional
+ */
+@Deprecated
+package org.apache.felix.jmx.service.coordination;
+
diff --git a/coordinator/src/main/java/org/apache/felix/service/coordination/Coordination.java b/coordinator/src/main/java/org/apache/felix/service/coordination/Coordination.java
new file mode 100644
index 0000000..6b785d0
--- /dev/null
+++ b/coordinator/src/main/java/org/apache/felix/service/coordination/Coordination.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
+ *
+ * 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.apache.felix.service.coordination;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * A Coordination object is used to coordinate a number of independent
+ * participants. Once a Coordination is created, it can be used to add
+ * Participant objects. When the Coordination is ended, the participants are
+ * called back. A Coordination can also fail for various reasons, in that case
+ * the participants are informed of this failure.
+ *
+ * @ThreadSafe
+ * @Provisional
+ */
+@Deprecated
+public interface Coordination {
+    /**
+     * Return value of end(). The Coordination ended normally, no participant
+     * threw an exception.
+     */
+    public static final int OK = 0;
+
+    /**
+     * Return value of end(). The Coordination did not end normally, a
+     * participant threw an exception making the outcome unclear.
+     */
+    public static final int PARTIALLY_ENDED = 1;
+
+    /**
+     * Return value of end(). The Coordination was set to always fail
+     * (fail(Throwable)).
+     */
+    public static final int FAILED = 2;
+
+    /**
+     * Return value of end(). The Coordination failed because it had timed out.
+     */
+    public static final int TIMEOUT = 3;
+
+    /**
+     * Return the name of this Coordination. The name is given in the
+     * Coordinator.begin(String) or Coordinator.create(String) method.
+     *
+     * @return the name of this Coordination
+     */
+    String getName();
+
+    /**
+     * Fail and then end this Coordination while returning the outcome. Any
+     * participants will be called on their Participant.failed(Coordination)
+     * method. Participants must assume that the Coordination failed and should
+     * discard and cleanup any work that was processed during this Coordination.
+     * The fail method must terminate the current Coordination before any of the
+     * failed methods are called. That is, the Participant.failed(Coordination)
+     * methods must be running outside the current coordination, no participants
+     * can be added during the termination phase. A fail method must return
+     * silently when the Coordination has already finished.
+     *
+     * @param reasonThrowable describing the reason of the failure for
+     *            documentation
+     * @return true if the Coordination was still active, otherwise false
+     */
+    boolean fail(Throwable reason);
+
+    /**
+     * If the Coordination is terminated then return, otherwise set the
+     * Coordination to fail. This method enables the following fail-safe pattern
+     * to ensure Coordinations are properly terminated.
+     *
+     * <pre>
+     * Coordination c = coordinator.begin("show_fail");
+     *     try {
+     *         work1();
+     *         work2();
+     *         if ( end() != OK )
+     *             log("...");
+     *     } catch( SomeException e) {
+     *         ...
+     *     } finally {
+     *         c.terminate();
+     *     }
+     * </pre>
+     * <p>
+     * With this pattern, it is easy to ensure that the coordination is always
+     * terminated.
+     *
+     * @return true if this method actually terminated the coordination (that
+     *         is, it was not properly ended). false if the Coordination was
+     *         already properly terminate by an end() or fail(Throwable) method.
+     */
+    boolean terminate();
+
+    /**
+     * End the current Coordination. Any participants will be called on their
+     * Participant.ended(Coordination) method. This end() method indicates that
+     * the Coordination has properly terminated and any participants should The
+     * end method must terminate the current Coordination before any of the
+     * Participant.ended(Coordination) methods is called. That is, the
+     * Participant.ended(Coordination) methods must be running outside the
+     * current coordination, no participants can be added during the termination
+     * phase. This method returns the outcome of the Coordination:
+     * <ol>
+     * <li>OK - Correct outcome, no exceptions thrown</li>
+     * <li>PARTIALLY_ENDED - One of the participants threw an exception</li>
+     * <li>FAILED - The Coordination was set to always fail</li>
+     * </ol>
+     *
+     * @return OK, PARTIALLY_ENDED, FAILED
+     * @throws IllegalStateException when the Coordination is already
+     *             terminated.
+     */
+    int end() throws IllegalStateException;
+
+    /**
+     * Return the current list of participants that joined the Coordination.
+     * This list is only valid as long as the Coordination has not been
+     * terminated. That is, after end() or fail(Throwable) is called this method
+     * will return an empty list.
+     *
+     * @return list of participants.
+     * @throws SecurityException This method requires the action for the
+     *             CoordinationPermission.
+     */
+    Collection<Participant> getParticipants();
+
+    /**
+     * @return true if this Coordination has failed, false otherwise.
+     */
+    boolean isFailed();
+
+    /**
+     * Add a minimum timeout for this Coordination. If this timeout expires,
+     * then the Coordination will fail and the initiating thread will be
+     * interrupted. This method must only be called on an active Coordination,
+     * that is, before end() or fail(Throwable) is called. If the current
+     * deadline is arriving later than the given timeout then the timeout is
+     * ignored.
+     *
+     * @param timeOutInMsNumber of ms to wait, zero means forever.
+     * @throws SecurityException This method requires the or action for the
+     *             CoordinationPermission. participate
+     */
+    void addTimeout(long timeOutInMs);
+
+    /**
+     * Add a Participant to this Coordination. If this method returns true then
+     * there was a current Coordination and the participant has successfully
+     * joined it. If there was no current Coordination then false is returned.
+     * Once a Participant is participating it is guaranteed to receive a call
+     * back on either the Participant.ended(Coordination) or
+     * Participant.failed(Coordination) method when the Coordination is
+     * terminated. A participant can be added to the Coordination multiple times
+     * but it must only be called back once when the Coordination is terminated.
+     * A Participant can only participate at a single Coordination, if it
+     * attempts to block at another Coordination, then it will block until prior
+     * Coordinations are finished. Notice that in edge cases the call back can
+     * happen before this method returns. The ordering of the call-backs must
+     * follow the order of participation. If participant is participating
+     * multiple times the first time it participates defines this order.
+     *
+     * @return true if the Coordination was active, otherwise false.
+     * @throws CoordinationException - This exception should normally not be
+     *             caught by the caller but allowed to bubble up to the
+     *             initiator of the coordination, it is therefore a
+     *             RuntimeException. It signals that this participant could not
+     *             participate the current coordination. This can be cause by
+     *             the following reasons:
+     *             <ol>
+     *             <li>CoordinationException.DEADLOCK_DETECTED</li>
+     *             <li>CoordinationException.TIMEOUT</li>
+     *             <li>CoordinationException.UNKNOWN</li>
+     *             </ol>
+     * @throws SecurityException This method requires the action for the current
+     *             Coordination, if any.
+     */
+    boolean participate(Participant p);
+
+    /**
+     * A utility map associated with the current Coordination. Each coordination
+     * carries a map that can be used for communicating between different
+     * participants. To namespace of the map is a class, allowing for private
+     * date to be stored in the map by using implementation classes or shared
+     * data by interfaces.
+     *
+     * @return The map
+     */
+    Map<Class<?>, ?> getVariables();
+}
diff --git a/coordinator/src/main/java/org/apache/felix/service/coordination/CoordinationException.java b/coordinator/src/main/java/org/apache/felix/service/coordination/CoordinationException.java
new file mode 100644
index 0000000..3e180cf
--- /dev/null
+++ b/coordinator/src/main/java/org/apache/felix/service/coordination/CoordinationException.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
+ *
+ * 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.apache.felix.service.coordination;
+
+/**
+ * Thrown when an implementation detects a potential deadlock situation that it
+ * cannot solve. The name of the current coordination is given as argument.
+ *
+ * @Provisional
+ */
+@Deprecated
+public class CoordinationException extends RuntimeException {
+
+    private static final long serialVersionUID = -4466063711012717361L;
+
+    /**
+     * Unknown reason fot this exception.
+     */
+    public static final int UNKNOWN = 0;
+
+    /**
+     * Adding a participant caused a deadlock.
+     */
+    public static final int DEADLOCK_DETECTED = 1;
+
+    /**
+     * The Coordination took too long to finish.
+     */
+    public static final int TIMEOUT = 2;
+
+    private final String name;
+
+    private final int reason;
+
+    /**
+     * Create a new Coordination Exception.
+     *
+     * @param message The message
+     * @param name The name of the Coordination
+     * @param reason The reason for the exception.
+     */
+    public CoordinationException(String message, String name, int reason) {
+        super(message);
+        this.name = name;
+        this.reason = reason;
+    }
+
+    /**
+     * Answer the name of the Coordination associated with this exception.
+     *
+     * @return the Coordination name
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Answer the reason.
+     *
+     * @return the reason
+     */
+    public int getReason() {
+        return reason;
+    }
+}
diff --git a/coordinator/src/main/java/org/apache/felix/service/coordination/CoordinationPermission.java b/coordinator/src/main/java/org/apache/felix/service/coordination/CoordinationPermission.java
new file mode 100644
index 0000000..5dd765f
--- /dev/null
+++ b/coordinator/src/main/java/org/apache/felix/service/coordination/CoordinationPermission.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
+ *
+ * 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.apache.felix.service.coordination;
+
+import java.security.BasicPermission;
+
+/**
+ * The name parameter of the Permission is a filter expression. It asserts the
+ * bundle that is associated with the coordination. Additionally, the following
+ * attributes can be asserted:
+ * <ol>
+ * <li>coordination.name - The name of the coordination
+ * <table>
+ * <tr>
+ * <td>Coordinator</td>
+ * <td>INITIATE</td>
+ * <td>PARTICIPATE</td>
+ * <td>ADMIN</td>
+ * <td>NONE</td>
+ * </tr>
+ * <tr>
+ * <td>alwaysFail(String)</td>
+ * <td></td>
+ * <td></td>
+ * <td>-</td>
+ * </tr>
+ * <tr>
+ * <td>begin(String) + -</td>
+ * </tr>
+ * <tr>
+ * <td>getCoordinations() + -</td>
+ * </tr>
+ * <tr>
+ * <td>isActive() + + + -</td>
+ * </tr>
+ * <tr>
+ * <td>isFailed() + + + -</td>
+ * </tr>
+ * <tr>
+ * <td>participate(Participant) + -</td>
+ * </tr>
+ * <tr>
+ * <td>participateOrBegin(Participant) + and + -</td>
+ * </tr>
+ * <tr>
+ * <td>Coordination</td>
+ * </tr>
+ * <tr>
+ * <td>end() +</td>
+ * </tr>
+ * <tr>
+ * <td>fail(String) +</td>
+ * </tr>
+ * <tr>
+ * <td>getName() +</td>
+ * </tr>
+ * <tr>
+ * <td>getParticipants() + -</td>
+ * </tr>
+ * <tr>
+ * <td>isFailed() +</td>
+ * </tr>
+ * <tr>
+ * <td>setTimeout(long) + + -</td>
+ * </tr>
+ * <tr>
+ * <td>terminate() +</td>
+ * </tr>
+ * </table>
+ * </li>
+ * </ol>
+ *
+ * @Provisional
+ */
+@Deprecated
+public class CoordinationPermission extends BasicPermission {
+
+    private static final long serialVersionUID = 1566605398519619478L;
+
+    /**
+     * Initiate a Coordination. An owner of this permission can initiate, end,
+     * fail, and terminate a Coordination.
+     */
+    public static final String INITIATE = "initiate";
+
+    /**
+     * The action string admin.
+     */
+    public static final String ADMIN = "admin";
+
+    /**
+     * The action string participate.
+     */
+    public static final String PARTICIPATE = "participate";
+
+    /**
+     * The name parameter specifies a filter condition. The filter asserts the
+     * bundle that initiated the Coordination. An implicit grant is made for a
+     * bundle's own coordinations. Parameters:
+     *
+     * @param filterExpression A filter expression asserting the bundle
+     *            associated with the coordination.
+     * @param actions A comma separated combination of INITIATE, ADMIN,
+     *            PARTICIPATE.
+     */
+    public CoordinationPermission(String filterExpression, String actions) {
+        super(filterExpression, actions);
+    }
+
+    /**
+     * The verification permission
+     *
+     * @param bundle The bundle that will be the target of the filter
+     *            expression.
+     * @param coordinationName The name of the coordination or null
+     * @param actions The set of actions required, which is a combination of
+     *            INITIATE, ADMIN, PARTICIPATE.
+     */
+    public CoordinationPermission(org.osgi.framework.Bundle bundle,
+            String coordinationName, String actions) {
+        super(coordinationName, actions);
+    }
+}
diff --git a/coordinator/src/main/java/org/apache/felix/service/coordination/Coordinator.java b/coordinator/src/main/java/org/apache/felix/service/coordination/Coordinator.java
new file mode 100644
index 0000000..4be5763
--- /dev/null
+++ b/coordinator/src/main/java/org/apache/felix/service/coordination/Coordinator.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
+ *
+ * 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.apache.felix.service.coordination;
+
+import java.util.Collection;
+
+/**
+ * A Coordinator service provides a facility to coordinate activities between
+ * different parties. The Coordinator is a factory of Coordination objects.
+ * Coordination objects can be created. Once created, they can be pushed on a
+ * thread local stack push(Coordination) as an implicit parameter for calls to
+ * other parties, or they can be passed as an argument. The current top of the
+ * thread local stack can be obtained with getCurrentCoordination(). The
+ * participate(Participant) method on this service or the
+ * Coordination.participate(Participant) method can be used to participate in a
+ * Coordination. Participants can only participate in a single Coordination, if
+ * a Participant object is added to two different Coordinations it will block
+ * until any prior Coordination has been ended. A Coordination can end correctly
+ * when the Coordination.end() method is called or when it fails. If the
+ * Coordination ends correctly, all its participants are called on the
+ * Participant.ended(Coordination) method, otherwise the
+ * Participant.failed(Coordination) is called. A Coordination can fail because
+ * it times out or it is explicitly failed. A Coordination will timeout after an
+ * implementation defined amount of time that must be higher than 30 seconds
+ * unless overridden with configuration. This time can be set on a per
+ * Coordination basis with the Coordination.addTimeout(long) method. The typical
+ * usage of the Coordinator service is as follows:
+ *
+ * <pre>
+ * Coordination coordination = coordinator.begin(&quot;mycoordination&quot;);
+ * try {
+ *     doWork();
+ *     if (coordination.end() != Coordination.OK) log(&quot;failed&quot;);
+ * } finally {
+ *     coordination.terminate();
+ * }
+ * </pre>
+ * <p>
+ * In the doWork() method, code can be called that requires a callback at the
+ * end of the Coordination. This code is for a Participant.
+ *
+ * <pre>
+ * void doWork() {
+ *     if (coordinator.participate(this)) {
+ *         beginWork();
+ *     } else {
+ *         beginWork();
+ *         finishWork();
+ *     }
+ * }
+ *
+ * void ended() {
+ *     finishWork();
+ * }
+ *
+ * void failed() {
+ *     undoWork();
+ * }
+ * </pre>
+ * <p>
+ * Life cycle. All Coordinations that are begun through this service must
+ * automatically fail before this service is ungotten.
+ *
+ * @ThreadSafe
+ * @Provisional
+ */
+@Deprecated
+public interface Coordinator {
+
+    /**
+     * Create a new Coordination that is not associated with the current thread.
+     * Parameters:
+     *
+     * @param name The name of this coordination, a name does not have to be
+     *            unique.
+     * @return The new Coordination object or null
+     * @throws SecurityException This method requires the action, no bundle
+     *             check is done.
+     */
+    Coordination create(String name);
+
+    /**
+     * Begin a new Coordination and push it on the thread local stack with
+     * push(Coordination). Parameters:
+     *
+     * @param name The name of this coordination, a name does not have to be
+     *            unique.
+     * @return A new Coordination object
+     * @throws SecurityException This method requires the action, no bundle
+     *             check is done.
+     */
+    Coordination begin(String name);
+
+    /**
+     * Associate the given Coordination object with a thread local stack. The
+     * top of the thread local stack is returned with the
+     * getCurrentCoordination() method. To remove the Coordination from the top
+     * call pop().
+     *
+     * @param c The Coordination to push
+     * @return c (for the builder pattern purpose)
+     */
+    Coordination push(Coordination c);
+
+    /**
+     * Pop the top of the thread local stack of Coordinations. If no current
+     * Coordination is present, return null.
+     *
+     * @return The top of the stack or null
+     */
+    Coordination pop();
+
+    /**
+     * Participate in the current Coordination or return false if there is none.
+     * This method calls getCurrentCoordination(), if it is null, it will return
+     * false. Otherwise it will call Coordination.participate(Participant) and
+     * return the result of that method.
+     *
+     * @param participant The participant of the Coordination
+     * @return true if there was a current Coordination that could be
+     *         successfully used to participate, otherwise false.
+     * @throws CoordinationException This exception should normally not be
+     *             caught by the caller but allowed to bubble up to the
+     *             initiator of the coordination, it is therefore a
+     *             RuntimeException. It signals that this participant could not
+     *             participate the current coordination. This can be cause by
+     *             the following reasons:
+     *             <ol>
+     *             <li>CoordinationException.DEADLOCK_DETECTED</li>
+     *             <li>CoordinationException.TIMEOUT</li>
+     *             <li>CoordinationException.UNKNOWN</li>
+     *             </ol>
+     * @throws SecurityException This method requires the action for the current
+     *             Coordination, if any.
+     */
+    boolean participate(Participant participant) throws CoordinationException;
+
+    /**
+     * Participate if there is an active Coordination otherwise initiate a new
+     * Coordination. This method is a short cut that atomically checks if there
+     * is a current Coordination. It either returns a new current Coordination
+     * object if no current Coordination exists or it adds the participant to
+     * the current Coordination. Notice that this method can block until the
+     * participant is free to participate on the current or new Coordination.
+     * This method makes it simple to start a new Coordination or to participate
+     * in an existing Coordination. See begin(String) and
+     * participate(Participant) for the details of those methods.
+     *
+     * @param ifActive The participant
+     * @return null if there is a current Coordination otherwise a newly
+     *         initiated Coordination.
+     * @throws SecurityException This method requires the action for the current
+     *             Coordination, if any. Otherwise it requires to create a new
+     *             coordination.
+     */
+    Coordination participateOrBegin(Participant ifActive);
+
+    /**
+     * Always fail the current Coordination, if exists. Must fail the current
+     * Coordination and return true or return false if there is no current
+     * Coordination.
+     *
+     * @param reason Throwable describing why the collaboration must always fail
+     *            for debugging or null.
+     * @return true if there was a current Coordination and false if not.
+     */
+    boolean alwaysFail(Throwable reason);
+
+    /**
+     * Return the current Coordination. The current Coordination is the top of
+     * the thread local stack of Coordinations. If the stack is empty, there is
+     * no current Coordination.
+     *
+     * @return null when the thread local stack is empty, otherwise the top of
+     *         the thread local stack of Coordinations.
+     */
+    Coordination getCurrentCoordination();
+
+    /**
+     * Provide a list of all Coordination objects. Answer a read only list of
+     * active Coordination. This list must be a mutable snapshot of the current
+     * situation. Changes to the list must not affect the original. Coordination
+     * objects are capabilities and designed to be used only on the Coordination
+     * thread. The returned list must only contain the Coordinations for which
+     * the caller has , without this permission an empty list must be returned.
+     *
+     * @return a list of Coordination objects
+     */
+    Collection<Coordination> getCoordinations();
+}
diff --git a/coordinator/src/main/java/org/apache/felix/service/coordination/Participant.java b/coordinator/src/main/java/org/apache/felix/service/coordination/Participant.java
new file mode 100644
index 0000000..2348c24
--- /dev/null
+++ b/coordinator/src/main/java/org/apache/felix/service/coordination/Participant.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
+ *
+ * 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.apache.felix.service.coordination;
+
+/**
+ * A Participant participates in a Coordination. A Participant can participate
+ * in a Coordination by calling Coordinator.participate(Participant) or
+ * Coordinator.participateOrBegin(Participant). After successfully initiating
+ * the participation, the Participant is called back when the Coordination is
+ * terminated. If a Coordination ends with the Coordination.end() method, then
+ * all the participants are called back on their ended(Coordination) method. If
+ * the initiator decides to fail the Coordination (or another party has called
+ * Coordinator.alwaysFail(Throwable)) then the failed(Coordination) method is
+ * called back. Participants are required to be thread safe for the
+ * ended(Coordination) method and the failed(Coordination) method. Both methods
+ * can be called on another thread. A Coordinator service must block a
+ * Participant when it tries to participate in multiple Coordinations.
+ *
+ * @ThreadSafe
+ * @Provisional
+ */
+@Deprecated
+public interface Participant {
+
+    /**
+     * The Coordination has failed and the participant is informed. A
+     * participant should properly discard any work it has done during the
+     * active coordination.
+     *
+     * @param c The Coordination that does the callback
+     * @throws Exception Any exception thrown should be logged but is further
+     *             ignored and does not influence the outcome of the
+     *             Coordination.
+     */
+    void failed(Coordination c) throws Exception;
+
+    /**
+     * The Coordination is being ended.
+     *
+     * @param c The Coordination that does the callback
+     * @throws Exception If an exception is thrown it should be logged and the
+     *             return of the Coordination.end() method must be
+     *             Coordination.PARTIALLY_ENDED.
+     */
+    void ended(Coordination c) throws Exception;
+}
diff --git a/coordinator/src/main/java/org/apache/felix/service/coordination/package-info.java b/coordinator/src/main/java/org/apache/felix/service/coordination/package-info.java
new file mode 100644
index 0000000..79837d3
--- /dev/null
+++ b/coordinator/src/main/java/org/apache/felix/service/coordination/package-info.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
+ *
+ * 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.
+ */
+/**
+ * Coordination Package Version 1.0.
+ * <p>
+ * Bundles wishing to use this package must list the package in the
+ * Import-Package header of the bundle's manifest.
+ * <p>
+ * This package has two types of users: the consumers that use the API in
+ * this package and the providers that  implement the API in this package.
+ * <p>
+ * Example import for consumers using the API in this package:
+ * <blockquote>
+ * <code>Import-Package: org.apache.felix.service.coordination; version="[1.0,2.0)"; status="provisional"</code>
+ * </blockquote>
+ * <p>
+ * Example import for providers implementing the API in this package:
+ * <blockquote>
+ * <code>Import-Package: org.apache.felix.service.coordination; version="[1.0,1.1)"; status="provisional"</code>
+ * </blockquote>
+ *
+ * @Provisional
+ */
+@Deprecated
+package org.apache.felix.service.coordination;
\ No newline at end of file