Adding apex context module

Change-Id: I1284c2ba4c41a9cf721e141e096d1021be599a2d
Issue-ID: POLICY-857
Signed-off-by: ramverma <ram.krishna.verma@ericsson.com>
diff --git a/context/context-management/pom.xml b/context/context-management/pom.xml
new file mode 100644
index 0000000..b05c76a
--- /dev/null
+++ b/context/context-management/pom.xml
@@ -0,0 +1,49 @@
+<!--
+  ============LICENSE_START=======================================================
+   Copyright (C) 2018 Ericsson. 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.
+
+  SPDX-License-Identifier: Apache-2.0
+  ============LICENSE_END=========================================================
+-->
+<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/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.onap.policy.apex-pdp.context</groupId>
+        <artifactId>context</artifactId>
+        <version>2.0.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>context-management</artifactId>
+    <name>${project.artifactId}</name>
+    <description>Context management for Apex policy execution</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.onap.policy.apex-pdp.model</groupId>
+            <artifactId>context-model</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onap.policy.apex-pdp.model</groupId>
+            <artifactId>utilities</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/ContextAlbum.java b/context/context-management/src/main/java/org/onap/policy/apex/context/ContextAlbum.java
new file mode 100644
index 0000000..73ef668
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/ContextAlbum.java
@@ -0,0 +1,127 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context;
+
+import java.util.Map;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum;
+
+/**
+ * The Interface ContextAlbum is implemented by all classes that manage context in Apex. Context albums may store
+ * context in memory, on disk, in a repository or in a mechanism such as a distributed map.
+ * <p>
+ * A context album uses plugins to handle its context schemas, its distribution, its locking, and its persistence.
+ * <p>
+ * The schema that defines the items in a context album is interpreted by a plugin that implements the
+ * {@link SchemaHelper} interface. The schema helper uses the schema definition to provide new instances for a context
+ * album. By default, context albums use Java schemas.
+ * <p>
+ * Context albums may be shared across an arbitrary number of JVMs using a distribution mechanism. Apex context
+ * distributed context albums using plugins that implement the {@link Distributor} interface. By default, context albums
+ * use JVM local distribution, that is context albums are only available in a single JVM
+ * <p>
+ * Items in a context album may be locked across all distributed instances of an album. Apex locks instances on context
+ * albums using the distributed locking mechanism in a plugin that implements the {@link LockManager} interface. By
+ * default, context albums use Java locking local to a single JVM on each context album instance.
+ * <p>
+ * Context albums may be persisted to disk, database, or any other repository. Apex persists context albums using the
+ * persistence mechanism in a plugin that implements the {@link Persistor} interface. By default, context albums use a
+ * dummy persistor plugin that does not persist context albums.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public interface ContextAlbum extends Map<String, Object> {
+    /**
+     * Gets the key of the context album instance.
+     *
+     * @return the key
+     */
+    AxArtifactKey getKey();
+
+    /**
+     * Gets the name of the context album instance.
+     *
+     * @return the name
+     */
+    String getName();
+
+    /**
+     * Get the current context album with values.
+     *
+     * @return the current context runtime values
+     */
+    AxContextAlbum getAlbumDefinition();
+
+    /**
+     * Get the schema helper for the technology that is handling the schema for this album.
+     *
+     * @return the schema helper
+     */
+    SchemaHelper getSchemaHelper();
+
+    /**
+     * Place a read lock on a key in this album across the entire cluster.
+     *
+     * @param key The key to lock
+     * @throws ContextException on locking errors
+     */
+    void lockForReading(String key) throws ContextException;
+
+    /**
+     * Place a write lock on a key in this album across the entire cluster.
+     *
+     * @param key The key to lock
+     * @throws ContextException on locking errors
+     */
+    void lockForWriting(String key) throws ContextException;
+
+    /**
+     * Release the the read lock on a key in this album across the entire cluster.
+     *
+     * @param key The key to unlock
+     * @throws ContextException on locking errors
+     */
+    void unlockForReading(String key) throws ContextException;
+
+    /**
+     * Release the the write lock on a key in this album across the entire cluster.
+     *
+     * @param key The key to unlock
+     * @throws ContextException on locking errors
+     */
+    void unlockForWriting(String key) throws ContextException;
+
+    /**
+     * Set the stack of artifact keys currently using this context item.
+     *
+     * @param userArtifactStack the keys of the artifacts using the context album at the moment
+     */
+    void setUserArtifactStack(AxConcept[] userArtifactStack);
+
+    /**
+     * Flush the context album to the distribution and persistence mechanism.
+     *
+     * @throws ContextException On context flush errors
+     */
+    void flush() throws ContextException;
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/ContextException.java b/context/context-management/src/main/java/org/onap/policy/apex/context/ContextException.java
new file mode 100644
index 0000000..de5cec0
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/ContextException.java
@@ -0,0 +1,51 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context;
+
+import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
+
+/**
+ * This exception will be called if an error occurs in an Apex context item.
+ *
+ * @author Liam Fallon
+ */
+public class ContextException extends ApexException {
+    private static final long serialVersionUID = -8507246953751956974L;
+
+    /**
+     * Instantiates a new apex context exception with a message.
+     *
+     * @param message the message
+     */
+    public ContextException(final String message) {
+        super(message);
+    }
+
+    /**
+     * Instantiates a new apex context exception with a message and a caused by exception.
+     *
+     * @param message the message
+     * @param e the exception that caused this exception to be thrown
+     */
+    public ContextException(final String message, final Exception e) {
+        super(message, e);
+    }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/ContextRuntimeException.java b/context/context-management/src/main/java/org/onap/policy/apex/context/ContextRuntimeException.java
new file mode 100644
index 0000000..b2aa017
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/ContextRuntimeException.java
@@ -0,0 +1,51 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context;
+
+import org.onap.policy.apex.model.basicmodel.concepts.ApexRuntimeException;
+
+/**
+ * This exception will be called if an error occurs in an Apex context item.
+ *
+ * @author Liam Fallon
+ */
+public class ContextRuntimeException extends ApexRuntimeException {
+    private static final long serialVersionUID = -8507246953751956974L;
+
+    /**
+     * Instantiates a new apex context exception with a message.
+     *
+     * @param message the message
+     */
+    public ContextRuntimeException(final String message) {
+        super(message);
+    }
+
+    /**
+     * Instantiates a new apex context exception with a message and a caused by exception.
+     *
+     * @param message the message
+     * @param e the exception that caused this exception to be thrown
+     */
+    public ContextRuntimeException(final String message, final Exception e) {
+        super(message, e);
+    }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/Distributor.java b/context/context-management/src/main/java/org/onap/policy/apex/context/Distributor.java
new file mode 100644
index 0000000..a173138
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/Distributor.java
@@ -0,0 +1,140 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextModel;
+
+/**
+ * This interface is implemented by plugin classes that distribute context albums in Apex.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public interface Distributor {
+
+    /**
+     * Initialize the distributor with its properties.
+     *
+     * @param key The key that identifies this distributor
+     * @throws ContextException On errors initializing the distributor
+     */
+    void init(AxArtifactKey key) throws ContextException;
+
+    /**
+     * Shut down distributor.
+     *
+     * @throws ContextException On errors initializing the distributor
+     */
+    void shutdown() throws ContextException;
+
+    /**
+     * Get the key of the distributor.
+     *
+     * @return the contextSetKey
+     */
+    AxArtifactKey getKey();
+
+    /**
+     * Register the context model and its sub models with the model service.
+     *
+     * @param contextModel the context model to register
+     * @throws ContextException on model registration errors
+     */
+    void registerModel(AxContextModel contextModel) throws ContextException;
+
+    /**
+     * Create a context album on a distributor, the distributor looks up the album and initialize it. The
+     * {@link AxContextAlbum} is used to check that the album in the distributor matches the album definition we expect
+     * to get.
+     *
+     * @param axContextAlbumKey the key of the model context album for this context album
+     * @return the context album
+     * @throws ContextException if the album cannot be initialised
+     */
+    ContextAlbum createContextAlbum(AxArtifactKey axContextAlbumKey) throws ContextException;
+
+    /**
+     * Remove a context album from a distributor.
+     *
+     * @param contextAlbum The album to remove
+     * @throws ContextException if the album cannot be removed
+     */
+    void removeContextAlbum(AxContextAlbum contextAlbum) throws ContextException;
+
+    /**
+     * Flush all context albums owned by the distributor to the distribution mechanism.
+     *
+     * @throws ContextException on context flushing errors
+     */
+    void flush() throws ContextException;
+
+    /**
+     * Flush a context album owned by the distributor to the distribution mechanism.
+     *
+     * @param contextAlbum the context album to flush
+     * @throws ContextException on errors in flushing the context album
+     */
+    void flushContextAlbum(ContextAlbum contextAlbum) throws ContextException;
+
+    /**
+     * Place a read lock on an item in an album across the entire cluster.
+     *
+     * @param albumKey The key of the album containing the item
+     * @param keyOnMap The key on the album to lock
+     * @throws ContextException on locking errors
+     */
+    void lockForReading(AxArtifactKey albumKey, String keyOnMap) throws ContextException;
+
+    /**
+     * Place a write lock on an album item across the entire cluster.
+     *
+     * @param albumKey The key of the album containing the item
+     * @param key The key on the album to lock
+     * @throws ContextException on locking errors
+     */
+    void lockForWriting(AxArtifactKey albumKey, String key) throws ContextException;
+
+    /**
+     * Release the read lock on a key across the entire cluster.
+     *
+     * @param albumKey The key of the album containing the item
+     * @param key The key on the album to unlock
+     * @throws ContextException on locking errors
+     */
+    void unlockForReading(AxArtifactKey albumKey, String key) throws ContextException;
+
+    /**
+     * Release the write lock on a key across the entire cluster.
+     *
+     * @param albumKey The key of the album containing the item
+     * @param key The key on the album to unlock
+     * @throws ContextException on locking errors
+     */
+    void unlockForWriting(AxArtifactKey albumKey, String key) throws ContextException;
+
+    /**
+     * Clear all the context from the context distributor.
+     *
+     * @throws ContextException on context clearing exceptions
+     */
+    void clear() throws ContextException;
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/LockManager.java b/context/context-management/src/main/java/org/onap/policy/apex/context/LockManager.java
new file mode 100644
index 0000000..8ccf544
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/LockManager.java
@@ -0,0 +1,88 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+
+/**
+ * This interface provides a facade to hide implementation details of various lock managers that may be used to manage
+ * locking of context items.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public interface LockManager {
+
+    /**
+     * Initialize the lock manager with its properties.
+     *
+     * @param key The key of this lock manager
+     * @throws ContextException On errors initializing the persistor
+     */
+    void init(AxArtifactKey key) throws ContextException;
+
+    /**
+     * Get the key of the lock manager.
+     *
+     * @return the managers key
+     */
+    AxArtifactKey getKey();
+
+    /**
+     * Place a read lock on a lock type and key across the entire cluster.
+     *
+     * @param lockTypeKey The key of the map where the context item to lock is
+     * @param lockKey The key on the map to lock
+     * @throws ContextException on locking errors
+     */
+    void lockForReading(String lockTypeKey, String lockKey) throws ContextException;
+
+    /**
+     * Place a write lock on a lock type and key across the entire cluster.
+     *
+     * @param lockTypeKey The key of the map where the context item to lock is
+     * @param lockKey The key on the map to lock
+     * @throws ContextException on locking errors
+     */
+    void lockForWriting(String lockTypeKey, String lockKey) throws ContextException;
+
+    /**
+     * Release a read lock on a lock type and key across the entire cluster.
+     *
+     * @param lockTypeKey The key of the map where the context item to lock is
+     * @param lockKey The key on the map to lock
+     * @throws ContextException on locking errors
+     */
+    void unlockForReading(String lockTypeKey, String lockKey) throws ContextException;
+
+    /**
+     * Release a write lock on a lock type and key across the entire cluster.
+     *
+     * @param lockTypeKey The key of the map where the context item to lock is
+     * @param lockKey The key on the map to lock
+     * @throws ContextException on locking errors
+     */
+    void unlockForWriting(String lockTypeKey, String lockKey) throws ContextException;
+
+    /**
+     * Shut down the lock manager and clear any connections or data it is using.
+     */
+    void shutdown();
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/Persistor.java b/context/context-management/src/main/java/org/onap/policy/apex/context/Persistor.java
new file mode 100644
index 0000000..d3218a3
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/Persistor.java
@@ -0,0 +1,79 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context;
+
+import java.util.Set;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+
+/**
+ * This interface is implemented by plugin classes that persist Context Albums in Apex.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public interface Persistor {
+
+    /**
+     * Initialize the persistor with its properties.
+     *
+     * @param key The key that identifies this persistor
+     * @throws ContextException On errors initializing the persistor
+     */
+    void init(AxArtifactKey key) throws ContextException;
+
+    /**
+     * Get the key of the persistor.
+     *
+     * @return the contextSetKey
+     */
+    AxArtifactKey getKey();
+
+    /**
+     * Read a context item from the persistence mechanism.
+     *
+     * @param key the key of the context item
+     * @param contextItemClassName the name of the context item class, a subclass of {@link AxContextSchema}
+     * @return the context item that has been read
+     * @throws ContextException on persistence read errors
+     */
+    AxContextSchema readContextItem(AxReferenceKey key, Class<?> contextItemClassName) throws ContextException;
+
+    /**
+     * Read all the values of a particular type from persistence.
+     *
+     * @param ownerKey the owner key
+     * @param contextItemClassName The class name of the objects to return
+     * @return the set of context item values read from persistence or null if none were found
+     * @throws ContextException On read errors
+     */
+    Set<AxContextSchema> readContextItems(AxArtifactKey ownerKey, Class<?> contextItemClassName)
+            throws ContextException;
+
+    /**
+     * Write a context item value to the persistence mechanism.
+     *
+     * @param contextItem the context item
+     * @return the context item that has been written
+     */
+    Object writeContextItem(Object contextItem);
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/SchemaHelper.java b/context/context-management/src/main/java/org/onap/policy/apex/context/SchemaHelper.java
new file mode 100644
index 0000000..aa6ea9f
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/SchemaHelper.java
@@ -0,0 +1,119 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context;
+
+import com.google.gson.JsonElement;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+
+/**
+ * This interface is implemented by plugin classes that use a particular schema to convert Apex context objects to an
+ * understandable form.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public interface SchemaHelper {
+
+    /**
+     * Initialize the schema helper with its properties.
+     *
+     * @param userKey The key that identifies the user of the schema helper
+     * @param schema the schema
+     * @throws ContextRuntimeException the context runtime exception
+     */
+    void init(AxKey userKey, AxContextSchema schema) throws ContextRuntimeException;
+
+    /**
+     * Get the user key of the schema helper.
+     *
+     * @return the user key
+     */
+    AxKey getUserKey();
+
+    /**
+     * Get the schema of the schema helper.
+     *
+     * @return the schema
+     */
+    AxContextSchema getSchema();
+
+    /**
+     * The Java class that this schema produces on the Java side.
+     *
+     * @return the schema class
+     */
+    Class<?> getSchemaClass();
+
+    /**
+     * The Java class that handles the schema for the schema technology in use.
+     *
+     * @return the schema object
+     */
+    Object getSchemaObject();
+
+    /**
+     * Create a new instance of the schema class using whatever schema technology is being used.
+     *
+     * @return the new instance
+     */
+    Object createNewInstance();
+
+    /**
+     * Create a new instance of the schema class using whatever schema technology is being used.
+     *
+     * @param stringValue the string represents the value the new instance should have
+     * @return the new instance
+     */
+    Object createNewInstance(String stringValue);
+
+    /**
+     * Create a new instance of the schema class from a GSON JsonElement using whatever schema technology is being used.
+     *
+     * @param jsonElement the JSON element that holds the Json representation of the object
+     * @return the new instance
+     */
+    Object createNewInstance(JsonElement jsonElement);
+
+    /**
+     * Unmarshal an object in schema format into a Java object.
+     *
+     * @param object the object as a Java object
+     * @return the object in schema format
+     */
+    Object unmarshal(Object object);
+
+    /**
+     * Marshal a Java object into Json format.
+     *
+     * @param schemaObject the object in schema format
+     * @return the object as a Json string
+     */
+    String marshal2Json(Object schemaObject);
+
+    /**
+     * Marshal a Java object into a GSON json element.
+     *
+     * @param schemaObject the object in schema format
+     * @return the object as a GSON Json element
+     */
+    JsonElement marshal2JsonElement(Object schemaObject);
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/ContextAlbumImpl.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/ContextAlbumImpl.java
new file mode 100644
index 0000000..a682716
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/ContextAlbumImpl.java
@@ -0,0 +1,486 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context.impl;
+
+import java.util.AbstractMap.SimpleEntry;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.onap.policy.apex.context.ContextAlbum;
+import org.onap.policy.apex.context.ContextException;
+import org.onap.policy.apex.context.ContextRuntimeException;
+import org.onap.policy.apex.context.Distributor;
+import org.onap.policy.apex.context.SchemaHelper;
+import org.onap.policy.apex.context.impl.schema.SchemaHelperFactory;
+import org.onap.policy.apex.context.monitoring.ContextMonitor;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum;
+import org.onap.policy.apex.model.utilities.Assertions;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * The Class ContextAlbumImpl implements the methods on the {@link ContextAlbum} interface. It implements the getters
+ * and setters on the {@link Map} and uses the {@link Distributor} to handle distribution and locking.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public final class ContextAlbumImpl implements ContextAlbum {
+    // Logger for this class
+    private static final XLogger LOGGER = XLoggerFactory.getXLogger(ContextAlbumImpl.class);
+
+    // The definition of this context album
+    private final AxContextAlbum albumDefinition;
+
+    /// The map holding the items and their values for this context album
+    private final Map<String, Object> albumMap;
+
+    // The artifact stack of the artifacts currently using the context album
+    private AxConcept[] userArtifactStack = null;
+
+    // The context distributor we are using
+    private final Distributor distributor;
+
+    // The schema helper that handles translations of Java objects for this album
+    private SchemaHelper schemaHelper;
+
+    // The context monitor for this context album
+    private ContextMonitor monitor = null;
+
+    /**
+     * Constructor, instantiate the context album.
+     *
+     * @param albumDefinition The model definition of this context album
+     * @param distributor The context distributor passed to us to distribute context across ContextAlbum instances
+     * @param albumMap the album map
+     * @throws ContextException on errors creating context albums
+     */
+    public ContextAlbumImpl(final AxContextAlbum albumDefinition, final Distributor distributor,
+            final Map<String, Object> albumMap) throws ContextException {
+        this.albumDefinition = albumDefinition;
+
+        // Use the context distributor passed to us
+        this.distributor = distributor;
+
+        // The map to use to store objects
+        this.albumMap = albumMap;
+
+        try {
+            // Get a schema helper to manage the translations between objects on the album map for this album
+            schemaHelper = new SchemaHelperFactory().createSchemaHelper(albumDefinition.getKey(),
+                    albumDefinition.getItemSchema());
+        } catch (final ContextRuntimeException e) {
+            final String resultString = "could not initiate schema management for context album " + albumDefinition;
+            LOGGER.warn(resultString, e);
+            throw new ContextException(resultString, e);
+        }
+
+        // Create the context monitor
+        monitor = new ContextMonitor();
+
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.context.ContextAlbum#getKey()
+     */
+    @Override
+    public AxArtifactKey getKey() {
+        return albumDefinition.getKey();
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.context.ContextAlbum#getName()
+     */
+    @Override
+    public String getName() {
+        return albumDefinition.getKey().getName();
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.context.ContextAlbum#getAxContextAlbum()
+     */
+    @Override
+    public AxContextAlbum getAlbumDefinition() {
+        return albumDefinition;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.context.ContextAlbum#getSchemaHelper()
+     */
+    @Override
+    public SchemaHelper getSchemaHelper() {
+        return schemaHelper;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.context.ContextAlbum#lockForReading(java.lang.String)
+     */
+    @Override
+    public void lockForReading(final String keyOnAlbum) throws ContextException {
+        distributor.lockForReading(albumDefinition.getKey(), keyOnAlbum);
+        monitor.monitorReadLock(albumDefinition.getKey(), albumDefinition.getItemSchema(), keyOnAlbum,
+                userArtifactStack);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.context.ContextAlbum#lockForWriting(java.lang.String)
+     */
+    @Override
+    public void lockForWriting(final String keyOnAlbum) throws ContextException {
+        distributor.lockForWriting(albumDefinition.getKey(), keyOnAlbum);
+        monitor.monitorWriteLock(albumDefinition.getKey(), albumDefinition.getItemSchema(), keyOnAlbum,
+                userArtifactStack);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.context.ContextAlbum#unlockForReading(java.lang.String)
+     */
+    @Override
+    public void unlockForReading(final String keyOnAlbum) throws ContextException {
+        distributor.unlockForReading(albumDefinition.getKey(), keyOnAlbum);
+        monitor.monitorReadUnlock(albumDefinition.getKey(), albumDefinition.getItemSchema(), keyOnAlbum,
+                userArtifactStack);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.context.ContextAlbum#unlockForWriting(java.lang.String)
+     */
+    @Override
+    public void unlockForWriting(final String keyOnAlbum) throws ContextException {
+        distributor.unlockForWriting(albumDefinition.getKey(), keyOnAlbum);
+        monitor.monitorWriteUnlock(albumDefinition.getKey(), albumDefinition.getItemSchema(), keyOnAlbum,
+                userArtifactStack);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see
+     * org.onap.policy.apex.context.ContextAlbum#setUserArtifactStack(org.onap.policy.apex.model.basicmodel.concepts.
+     * AxConcept [])
+     */
+    @Override
+    public void setUserArtifactStack(final AxConcept[] userArtifactStack) {
+        this.userArtifactStack = userArtifactStack;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.context.ContextAlbum#flush()
+     */
+    @Override
+    public void flush() throws ContextException {
+        distributor.flushContextAlbum(this);
+    }
+
+    /*
+     * The Map interface
+     */
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.util.Map#size()
+     */
+    @Override
+    public int size() {
+        return albumMap.size();
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.util.Map#isEmpty()
+     */
+    @Override
+    public boolean isEmpty() {
+        return albumMap.isEmpty();
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.util.Map#containsKey(java.lang.Object)
+     */
+    @Override
+    public boolean containsKey(final Object key) {
+        if (key == null) {
+            LOGGER.warn("null values are illegal on method parameter \"key\"");
+            throw new ContextRuntimeException("null values are illegal on method parameter \"key\"");
+        }
+
+        return albumMap.containsKey(key);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.util.Map#containsValue(java.lang.Object)
+     */
+    @Override
+    public boolean containsValue(final Object value) {
+        if (value == null) {
+            LOGGER.warn("null values are illegal on method parameter \"value\"");
+            throw new ContextRuntimeException("null values are illegal on method parameter \"value\"");
+        }
+
+        return albumMap.containsValue(value);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.util.Map#get(java.lang.Object)
+     */
+    @Override
+    public Object get(final Object key) {
+        if (key == null) {
+            final String returnString =
+                    "album \"" + albumDefinition.getID() + "\" null keys are illegal on keys for get()";
+            LOGGER.warn(returnString);
+            throw new ContextRuntimeException(returnString);
+        }
+
+        final Object item = albumMap.get(key);
+        if (item == null) {
+            return null;
+        }
+
+        // Get the context value and monitor it
+        monitor.monitorGet(albumDefinition.getKey(), albumDefinition.getItemSchema(), key.toString(), item,
+                userArtifactStack);
+        return item;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.util.Map#keySet()
+     */
+    @Override
+    public Set<String> keySet() {
+        return albumMap.keySet();
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.util.Map#values()
+     */
+    @Override
+    public Collection<Object> values() {
+        // Build the key set and return it
+        final ArrayList<Object> valueList = new ArrayList<>();
+
+        for (final Entry<String, Object> contextAlbumEntry : albumMap.entrySet()) {
+            final Object item = contextAlbumEntry.getValue();
+            monitor.monitorGet(albumDefinition.getKey(), albumDefinition.getItemSchema(), contextAlbumEntry.getKey(),
+                    item, userArtifactStack);
+            valueList.add(contextAlbumEntry.getValue());
+        }
+
+        return valueList;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.util.Map#entrySet()
+     */
+    @Override
+    public Set<Entry<String, Object>> entrySet() {
+        // Build the entry set and return it
+        final Set<Entry<String, Object>> entrySet = new HashSet<>();
+
+        for (final Entry<String, Object> contextAlbumEntry : albumMap.entrySet()) {
+            final Object item = contextAlbumEntry.getValue();
+            monitor.monitorGet(albumDefinition.getKey(), albumDefinition.getItemSchema(), contextAlbumEntry.getKey(),
+                    item, userArtifactStack);
+            entrySet.add(new SimpleEntry<>(contextAlbumEntry.getKey(), contextAlbumEntry.getValue()));
+        }
+
+        return entrySet;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.util.Map#put(java.lang.Object, java.lang.Object)
+     */
+    @Override
+    public Object put(final String key, final Object incomingValue) {
+        if (key == null) {
+            final String returnString =
+                    "album \"" + albumDefinition.getID() + "\" null keys are illegal on keys for put()";
+            LOGGER.warn(returnString);
+            throw new ContextRuntimeException(returnString);
+        }
+
+        if (incomingValue == null) {
+            final String returnString = "album \"" + albumDefinition.getID() + "\" null values are illegal on key \""
+                    + key + "\" for put()";
+            LOGGER.warn(returnString);
+            throw new ContextRuntimeException(returnString);
+        }
+
+        if (!albumDefinition.isWritable()) {
+            final String returnString = "album \"" + albumDefinition.getID()
+                    + "\" put() not allowed on read only albums for key=\"" + key + "\", value=\"" + incomingValue;
+            LOGGER.warn(returnString);
+            throw new ContextRuntimeException(returnString);
+        }
+
+        try {
+            // Translate the object to a schema object
+            final Object valueToPut = schemaHelper.unmarshal(incomingValue);
+
+            // Check if the key is already in the map
+            if (albumMap.containsKey(key)) {
+                // Update the value in the context item and in the context value map
+                monitor.monitorSet(albumDefinition.getKey(), albumDefinition.getItemSchema(), key, incomingValue,
+                        userArtifactStack);
+            } else {
+                // Update the value in the context item and in the context value map
+                monitor.monitorInit(albumDefinition.getKey(), albumDefinition.getItemSchema(), key, incomingValue,
+                        userArtifactStack);
+            }
+
+            // Put the translated value on the map and return the old map value
+            return albumMap.put(key, valueToPut);
+        } catch (final ContextRuntimeException e) {
+            final String returnString = "Failed to set context value for key \"" + key + "\" in album \""
+                    + albumDefinition.getID() + "\": " + e.getMessage();
+            LOGGER.warn(returnString);
+            throw new ContextRuntimeException(returnString, e);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.util.Map#putAll(java.util.Map)
+     */
+    @Override
+    public void putAll(final Map<? extends String, ? extends Object> incomingContextAlbum) {
+        if (!albumDefinition.isWritable()) {
+            final String returnString =
+                    "album \"" + albumDefinition.getID() + "\" putAll() not allowed on read only albums";
+            LOGGER.warn(returnString);
+            throw new ContextRuntimeException(returnString);
+        }
+
+        // Sanity check on incoming context
+        Assertions.argumentNotNull(incomingContextAlbum, ContextRuntimeException.class,
+                "cannot update context, context album is null");
+
+        // Iterate over the incoming context
+        for (final Entry<String, Object> entry : albumMap.entrySet()) {
+            synchronized (albumDefinition) {
+                // Get the key for the incoming name
+                final Object incomingDataItem = incomingContextAlbum.get(entry.getKey());
+                if (incomingDataItem != null) {
+                    // Update the value the context album
+                    put(entry.getKey(), incomingDataItem);
+                }
+            }
+        }
+
+        // Put all the objects on the context album
+        for (final Entry<? extends String, ? extends Object> incomingMapEntry : incomingContextAlbum.entrySet()) {
+            // Put the entry on the map
+            this.put(incomingMapEntry.getKey(), incomingMapEntry.getValue());
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.util.Map#remove(java.lang.Object)
+     */
+    @Override
+    public Object remove(final Object key) {
+        if (!albumDefinition.isWritable()) {
+            final String returnString = "album \"" + albumDefinition.getID()
+                    + "\" remove() not allowed on read only albums for key=\"" + key;
+            LOGGER.warn(returnString);
+            throw new ContextRuntimeException(returnString);
+        }
+
+        if (key == null) {
+            LOGGER.warn("null values are illegal on method parameter \"key\"");
+            throw new ContextRuntimeException("null values are illegal on method parameter \"keyID\"");
+        }
+
+        // Delete the item
+        final Object removedValue = albumMap.remove(key);
+        monitor.monitorDelete(albumDefinition.getKey(), albumDefinition.getItemSchema(), key.toString(), removedValue,
+                userArtifactStack);
+
+        // Return the value of the deleted item
+        return removedValue;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.util.Map#clear()
+     */
+    @Override
+    public void clear() {
+        if (!albumDefinition.isWritable()) {
+            final String returnString =
+                    "album \"" + albumDefinition.getID() + "\" clear() not allowed on read only albums";
+            LOGGER.warn(returnString);
+            throw new ContextRuntimeException(returnString);
+        }
+
+        // Monitor deletion of each item
+        for (final Entry<String, Object> contextAlbumEntry : albumMap.entrySet()) {
+            final Object item = contextAlbumEntry.getValue();
+            monitor.monitorDelete(albumDefinition.getKey(), albumDefinition.getItemSchema(), contextAlbumEntry.getKey(),
+                    item, userArtifactStack);
+        }
+
+        // Clear the map
+        albumMap.clear();
+    }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/AbstractDistributor.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/AbstractDistributor.java
new file mode 100644
index 0000000..e5a45b2
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/AbstractDistributor.java
@@ -0,0 +1,326 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context.impl.distribution;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.onap.policy.apex.context.ContextAlbum;
+import org.onap.policy.apex.context.ContextException;
+import org.onap.policy.apex.context.Distributor;
+import org.onap.policy.apex.context.LockManager;
+import org.onap.policy.apex.context.Persistor;
+import org.onap.policy.apex.context.impl.ContextAlbumImpl;
+import org.onap.policy.apex.context.impl.locking.LockManagerFactory;
+import org.onap.policy.apex.context.impl.persistence.PersistorFactory;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInformation;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.service.ModelService;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbums;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextModel;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchemas;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * This context distributor implements the mechanism-neutral parts of a context distributor.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public abstract class AbstractDistributor implements Distributor {
+
+    // Logger for this class
+    private static final XLogger LOGGER = XLoggerFactory.getXLogger(AbstractDistributor.class);
+
+    // The key of this distributor
+    private AxArtifactKey key = null;
+
+    // The context albums for this context set indexed by their keys
+    private static Map<AxArtifactKey, ContextAlbum> albumMaps =
+            Collections.synchronizedMap(new HashMap<AxArtifactKey, ContextAlbum>());
+
+    // Lock manager for this distributor
+    private static LockManager lockManager = null;
+
+    // Hold a persistor for this distributor
+    private Persistor persistor = null;
+
+    // Hold a flush timer for this context distributor
+    private static DistributorFlushTimerTask flushTimer = null;
+
+    /**
+     * Create an instance of an abstract Context Distributor.
+     */
+    public AbstractDistributor() {
+        LOGGER.entry("AbstractContextDistributor()");
+        LOGGER.exit("AbstractContextDistributor()");
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.context.ContextDistributor#init(org.onap.policy.apex.model.basicmodel.concepts.
+     * AxArtifactKey)
+     */
+    @Override
+    public void init(final AxArtifactKey distributorKey) throws ContextException {
+        LOGGER.entry("init(" + distributorKey + ")");
+
+        // Record parameters and key
+        this.key = distributorKey;
+
+        // Create the lock manager if it doesn't already exist
+        if (lockManager == null) {
+            lockManager = new LockManagerFactory().createLockManager(key);
+        }
+
+        // Set up flushing on the context distributor if its not set up already
+        if (flushTimer == null) {
+            flushTimer = new DistributorFlushTimerTask(this);
+        }
+
+        // Create a new persistor for this key
+        persistor = new PersistorFactory().createPersistor(key);
+        LOGGER.exit("init(" + key + ")");
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.context.ContextDistributor#shutdown()
+     */
+    @Override
+    public abstract void shutdown();
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.context.ContextDistributor#getKey()
+     */
+    @Override
+    public AxArtifactKey getKey() {
+        return key;
+    }
+
+    /**
+     * Create a context album using whatever underlying mechanism we are using for albums.
+     *
+     * @param contextAlbumKey The key of the album
+     * @return The album as a string-object map
+     */
+    public abstract Map<String, Object> getContextAlbumMap(AxArtifactKey contextAlbumKey);
+
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.context.Distributor#registerModel(org.onap.policy.apex.model.contextmodel.concepts.
+     * AxContextModel)
+     */
+    @Override
+    public void registerModel(final AxContextModel contextModel) throws ContextException {
+        ModelService.registerModel(AxKeyInformation.class, contextModel.getKeyInformation());
+        ModelService.registerModel(AxContextSchemas.class, contextModel.getSchemas());
+        ModelService.registerModel(AxContextAlbums.class, contextModel.getAlbums());
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see
+     * org.onap.policy.apex.core.context.ContextDistributor#createContextAlbum(org.onap.policy.apex.core.basicmodel.
+     * concepts. AxArtifactKey)
+     */
+    @Override
+    public synchronized ContextAlbum createContextAlbum(final AxArtifactKey axContextAlbumKey) throws ContextException {
+        // Get the context album definition
+        final AxContextAlbum album = ModelService.getModel(AxContextAlbums.class).get(axContextAlbumKey);
+        if (album == null) {
+            final String resultString = "context album " + axContextAlbumKey.getID() + " does not exist";
+            LOGGER.warn(resultString);
+            throw new ContextException(resultString);
+        }
+
+        // Check if the context album is valid
+        final AxValidationResult result = album.validate(new AxValidationResult());
+        if (!result.isValid()) {
+            final String resultString =
+                    "context album definition for " + album.getKey().getID() + " is invalid" + result;
+            LOGGER.warn(resultString);
+            throw new ContextException(resultString);
+        }
+
+        // Get the schema of the context album
+        final AxContextSchema schema = ModelService.getModel(AxContextSchemas.class).get(album.getItemSchema());
+        if (schema == null) {
+            final String resultString = "schema \"" + album.getItemSchema().getID() + "\" for context album "
+                    + album.getKey().getID() + " does not exist";
+            LOGGER.warn(resultString);
+            throw new ContextException(resultString);
+        }
+
+        // Check if the map has already been instantiated
+        if (!albumMaps.containsKey(album.getKey())) {
+            // Instantiate the album map for this context album that we'll distribute using the distribution mechanism
+            final Map<String, Object> newContextAlbumMap = getContextAlbumMap(album.getKey());
+
+            // The distributed context album will have content from another process instance if the album exists in
+            // another process,
+            // if not, we have to try to read the content from persistence
+            if (newContextAlbumMap.isEmpty()) {
+                // Read entries from persistence
+                // TODO: READ ITEMS FROM PRESISTENCE!!!!
+            }
+
+            // Create the context album and put the context album object onto the distributor
+            albumMaps.put(album.getKey(), new ContextAlbumImpl(album, this, newContextAlbumMap));
+        }
+
+        return albumMaps.get(album.getKey());
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see
+     * org.onap.policy.apex.core.context.ContextDistributor#removeContextAlbum(org.onap.policy.apex.core.basicmodel.
+     * concepts. AxArtifactKey)
+     */
+    @Override
+    public void removeContextAlbum(final AxContextAlbum contextAlbum) throws ContextException {
+        // Check if the map already exists, if not return
+        if (!albumMaps.containsKey(contextAlbum.getKey())) {
+            LOGGER.warn("map remove failed, supplied map is null");
+            throw new ContextException("map update failed, supplied map is null");
+        }
+
+        // Remove the map from the distributor
+        albumMaps.remove(contextAlbum.getKey());
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.core.context.ContextDistributor#flush()
+     */
+    @Override
+    public void flush() throws ContextException {
+        // Flush all the maps
+        for (final Entry<AxArtifactKey, ContextAlbum> distributorMapEntry : albumMaps.entrySet()) {
+            // Let the persistor write each of the entries
+            for (final Object contextItem : distributorMapEntry.getValue().values()) {
+                LOGGER.debug(contextItem.toString());
+                // persistor.writeContextItem((AxContextSchema) contextItem);
+            }
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.core.context.ContextDistributor#flushContextAlbum(org.onap.policy.apex.core.context.
+     * ContextAlbum)
+     */
+    @Override
+    public void flushContextAlbum(final ContextAlbum contextAlbum) throws ContextException {
+        // Check if the map already exists, if not return
+        if (!albumMaps.containsKey(contextAlbum.getKey())) {
+            LOGGER.warn("map flush failed, supplied map is null");
+            throw new ContextException("map flush failed, supplied map is null");
+        }
+
+        // Let the persistor flush the items on the map
+        for (final Object contextItem : albumMaps.get(contextAlbum.getKey()).values()) {
+            persistor.writeContextItem(contextItem);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.core.context.ContextDistributor#lockForReading(java.lang.String)
+     */
+    @Override
+    public synchronized void lockForReading(final AxArtifactKey mapKey, final String itemKey) throws ContextException {
+        // Lock using the lock manager
+        lockManager.lockForReading(mapKey.getID(), itemKey);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.core.context.ContextDistributor#lockForWriting(java.lang.String)
+     */
+    @Override
+    public synchronized void lockForWriting(final AxArtifactKey mapKey, final String itemKey) throws ContextException {
+        // Lock using the lock manager
+        lockManager.lockForWriting(mapKey.getID(), itemKey);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.core.context.ContextDistributor#unlockForReading(java.lang.String)
+     */
+    @Override
+    public void unlockForReading(final AxArtifactKey mapKey, final String itemKey) throws ContextException {
+        // Unlock using the lock manager
+        lockManager.unlockForReading(mapKey.getID(), itemKey);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.core.context.ContextDistributor#unlockForWriting(java.lang.String)
+     */
+    @Override
+    public void unlockForWriting(final AxArtifactKey mapKey, final String itemKey) throws ContextException {
+        // Unlock using the lock manager
+        lockManager.unlockForWriting(mapKey.getID(), itemKey);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.core.context.ContextDistributor#clear()
+     */
+    @Override
+    public void clear() {
+        // Shut down the lock manager
+        if (lockManager != null) {
+            lockManager.shutdown();
+            lockManager = null;
+        }
+
+        albumMaps.clear();
+
+        // Turn off the flush timer
+        flushTimer.cancel();
+
+        // Shut down the specialization of the context distributor
+        shutdown();
+    }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/DistributorFactory.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/DistributorFactory.java
new file mode 100644
index 0000000..1af13cb
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/DistributorFactory.java
@@ -0,0 +1,86 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context.impl.distribution;
+
+import org.onap.policy.apex.context.ContextException;
+import org.onap.policy.apex.context.Distributor;
+import org.onap.policy.apex.context.parameters.DistributorParameters;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.service.ParameterService;
+import org.onap.policy.apex.model.utilities.Assertions;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * This class returns a context distributor for the particular type of distribution mechanism configured for use.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class DistributorFactory {
+    // Get a reference to the logger
+    private static final XLogger LOGGER = XLoggerFactory.getXLogger(DistributorFactory.class);
+
+    /**
+     * Get a context distributor for a given context set key.
+     *
+     * @param key The key for the distributor
+     * @return a context distributor
+     * @throws ContextException on context distributor creation errors
+     */
+    public Distributor getDistributor(final AxArtifactKey key) throws ContextException {
+        LOGGER.entry("Distributor factory, key=" + key);
+
+        Assertions.argumentNotNull(key, ContextException.class, "Parameter \"key\" may not be null");
+
+        // Get the class for the distributor using reflection
+        final DistributorParameters distributorParameters = ParameterService.getParameters(DistributorParameters.class);
+        final String pluginClass = distributorParameters.getPluginClass();
+        Object contextDistributorObject = null;
+        try {
+            contextDistributorObject = Class.forName(pluginClass).newInstance();
+        } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
+            LOGGER.error(
+                    "Apex context distributor class not found for context distributor plugin \"" + pluginClass + "\"",
+                    e);
+            throw new ContextException(
+                    "Apex context distributor class not found for context distributor plugin \"" + pluginClass + "\"",
+                    e);
+        }
+
+        // Check the class is a distributor
+        if (!(contextDistributorObject instanceof Distributor)) {
+            final String returnString = "Specified Apex context distributor plugin class \"" + pluginClass
+                    + "\" does not implement the ContextDistributor interface";
+            LOGGER.error(returnString);
+            throw new ContextException(returnString);
+        }
+
+        // The context Distributor to return
+        final Distributor contextDistributor = (Distributor) contextDistributorObject;
+
+        // Lock and load the context distributor
+        contextDistributor.init(key);
+
+        LOGGER.exit(
+                "Distributor factory, key=" + key + ", selected distributor of class " + contextDistributor.getClass());
+        return contextDistributor;
+    }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/DistributorFlushTimerTask.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/DistributorFlushTimerTask.java
new file mode 100644
index 0000000..467d43f
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/DistributorFlushTimerTask.java
@@ -0,0 +1,116 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context.impl.distribution;
+
+import java.util.Timer;
+import java.util.TimerTask;
+
+import org.onap.policy.apex.context.ContextException;
+import org.onap.policy.apex.context.Distributor;
+import org.onap.policy.apex.context.parameters.PersistorParameters;
+import org.onap.policy.apex.model.basicmodel.service.ParameterService;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * This class is used to periodically flush a context distributor.
+ *
+ * @author eeilfn
+ */
+public class DistributorFlushTimerTask extends TimerTask {
+    private static final XLogger LOGGER = XLoggerFactory.getXLogger(DistributorFlushTimerTask.class);
+
+    // The timer for flushing
+    private Timer timer = null;
+
+    // The context distributor to flush
+    private final Distributor contextDistributor;
+
+    // Timing information
+    private long period = 0;
+    private long flushCount = 0;
+
+    /**
+     * Constructor, save a reference to the event stream handler.
+     *
+     * @param contextDistributor the distributor that this timer task is flushing
+     * @throws ContextException On flush setup errors
+     */
+    public DistributorFlushTimerTask(final Distributor contextDistributor) throws ContextException {
+        // Save the context distributor and period
+        this.contextDistributor = contextDistributor;
+
+        // Set the period for persistence flushing
+        final PersistorParameters persistorParameters = ParameterService.getParameters(PersistorParameters.class);
+        period = persistorParameters.getFlushPeriod();
+
+        // Set up the timer
+        timer = new Timer(DistributorFlushTimerTask.class.getSimpleName(), true);
+        timer.schedule(this, period, period);
+
+        LOGGER.debug("context distributor " + contextDistributor.getKey().getID() + " flushing set up with interval: "
+                + period + "ms");
+    }
+
+    /**
+     * Flush the context distributor.
+     */
+    @Override
+    public void run() {
+        // Increment the flush counter
+        flushCount++;
+
+        LOGGER.debug("context distributor " + contextDistributor.getKey().getID() + " flushing: period=" + period
+                + ": count=" + flushCount);
+        try {
+            contextDistributor.flush();
+            LOGGER.debug("context distributor " + contextDistributor.getKey().getID() + " flushed: period=" + period
+                    + ": count=" + flushCount);
+        } catch (final ContextException e) {
+            LOGGER.error("flush error on context distributor " + contextDistributor.getKey().getID() + ": period="
+                    + period + ": count=" + flushCount, e);
+        }
+    }
+
+    /**
+     * Cancel the timer.
+     *
+     * @return true, if cancel
+     */
+    @Override
+    public boolean cancel() {
+        // Cancel the timer
+        if (timer != null) {
+            timer.cancel();
+        }
+        return true;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return "ContextDistributorFlushTimerTask [period=" + period + ", flushCount=" + flushCount + "]";
+    }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/jvmlocal/JVMLocalDistributor.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/jvmlocal/JVMLocalDistributor.java
new file mode 100644
index 0000000..dc66372
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/jvmlocal/JVMLocalDistributor.java
@@ -0,0 +1,70 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context.impl.distribution.jvmlocal;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.onap.policy.apex.context.impl.distribution.AbstractDistributor;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * This context distributor distributes context across threads in a single JVM. It holds context in memory in a map.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class JVMLocalDistributor extends AbstractDistributor {
+    // Logger for this class
+    private static final XLogger LOGGER = XLoggerFactory.getXLogger(JVMLocalDistributor.class);
+
+    /**
+     * Create an instance of a JVM Local Context Distributor.
+     */
+    public JVMLocalDistributor() {
+        super();
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see
+     * org.onap.policy.apex.context.impl.distribution.AbstractDistributor#getContextAlbumMap(org.onap.policy.apex.model.
+     * basicmodel.concepts.AxArtifactKey)
+     */
+    @Override
+    public Map<String, Object> getContextAlbumMap(final AxArtifactKey contextMapKey) {
+        LOGGER.debug("create map: " + contextMapKey.getID());
+        return Collections.synchronizedMap(new HashMap<String, Object>());
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.context.impl.distribution.AbstractDistributor#shutdown()
+     */
+    @Override
+    public void shutdown() {
+        // No specific shutdown for the JVMLocalContextDistributor
+    }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/jvmlocal/package-info.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/jvmlocal/package-info.java
new file mode 100644
index 0000000..d964200
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/jvmlocal/package-info.java
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+/**
+ * Provides the JVM local default context distribution mechanism for APEX.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+
+package org.onap.policy.apex.context.impl.distribution.jvmlocal;
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/package-info.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/package-info.java
new file mode 100644
index 0000000..9b21eed
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/package-info.java
@@ -0,0 +1,28 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+/**
+ * Provides an implementation of context album distribution that uses a distribution plugin to distribute items in APEX
+ * context albums. It also provides a default JVM local distribution plugin.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+
+package org.onap.policy.apex.context.impl.distribution;
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/locking/AbstractLockManager.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/locking/AbstractLockManager.java
new file mode 100644
index 0000000..4f197e2
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/locking/AbstractLockManager.java
@@ -0,0 +1,225 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context.impl.locking;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.locks.ReadWriteLock;
+
+import org.onap.policy.apex.context.ContextException;
+import org.onap.policy.apex.context.LockManager;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * This class implements the {@link LockManager} functionality that is common across all implementations. Lock managers
+ * for specific lock mechanisms specialize this class.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public abstract class AbstractLockManager implements LockManager {
+    // Logger for this class
+    private static final XLogger LOGGER = XLoggerFactory.getXLogger(AbstractLockManager.class);
+
+    // The key of this lock manager
+    private AxArtifactKey key = null;
+
+    // Map of locks in use on this distributor for each context map
+    private final Map<String, Map<String, ReadWriteLock>> lockMaps =
+            Collections.synchronizedMap(new HashMap<String, Map<String, ReadWriteLock>>());
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.context.LockManager#init(org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey)
+     */
+    @Override
+    public void init(final AxArtifactKey lockManagerKey) throws ContextException {
+        this.key = lockManagerKey;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.context.LockManager#getKey()
+     */
+    @Override
+    public AxArtifactKey getKey() {
+        return key;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.core.context.LockManager#lockForReading(org.onap.policy.apex.core.model.concepts.
+     * AxArtifactKey, java.lang.String)
+     */
+    @Override
+    public synchronized void lockForReading(final String lockTypeKey, final String lockKey) throws ContextException {
+        LOGGER.entry("lockForReading(" + lockTypeKey + "_" + lockKey + ")");
+
+        // Find the lock or create a new one
+        final ReadWriteLock lock = getLock(lockTypeKey, lockKey, true);
+
+        try {
+            lock.readLock().lock();
+            LOGGER.exit("lockForReading(" + lockTypeKey + "_" + lockKey + ")");
+        } catch (final Exception e) {
+            LOGGER.warn("error acquiring read lock on context map " + lockTypeKey + " context item " + lockKey, e);
+            throw new ContextException(
+                    "error acquiring read lock on context map " + lockTypeKey + " context item " + lockKey, e);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.core.context.LockManager#lockForWriting(java.lang.String, java.lang.String)
+     */
+    @Override
+    public synchronized void lockForWriting(final String lockTypeKey, final String lockKey) throws ContextException {
+        LOGGER.entry("lockForWriting(" + lockTypeKey + "_" + lockKey + ")");
+
+        // Find the lock or create a new one
+        final ReadWriteLock lock = getLock(lockTypeKey, lockKey, true);
+
+        try {
+            lock.writeLock().lock();
+            LOGGER.exit("lockForWriting(" + lockTypeKey + "_" + lockKey + ")");
+        } catch (final Exception e) {
+            LOGGER.warn("error acquiring write lock on context map " + lockTypeKey + " context item " + lockKey, e);
+            throw new ContextException(
+                    "error acquiring write lock on context map " + lockTypeKey + " context item " + lockKey, e);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.core.context.LockManager#unlockForReading(java.lang.String, java.lang.String)
+     */
+    @Override
+    public void unlockForReading(final String lockTypeKey, final String lockKey) throws ContextException {
+        LOGGER.entry("unlockForReading(" + lockTypeKey + "_" + lockKey + ")");
+
+        // Find the lock
+        final ReadWriteLock lock = getLock(lockTypeKey, lockKey, false);
+
+        try {
+            lock.readLock().unlock();
+            LOGGER.exit("unlockForReading(" + lockTypeKey + "_" + lockKey + ")");
+        } catch (final Exception e) {
+            LOGGER.warn("error releasing read lock on context map " + lockTypeKey + " context item " + lockKey, e);
+            throw new ContextException(
+                    "error releasing read lock on context map " + lockTypeKey + " context item " + lockKey, e);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.core.context.LockManager#unlockForWriting(java.lang.String, java.lang.String)
+     */
+    @Override
+    public void unlockForWriting(final String lockTypeKey, final String lockKey) throws ContextException {
+        LOGGER.entry("unlockForWriting(" + lockTypeKey + "_" + lockKey + ")");
+
+        // Find the lock
+        final ReadWriteLock lock = getLock(lockTypeKey, lockKey, false);
+
+        try {
+            lock.writeLock().unlock();
+            LOGGER.exit("unlockForWriting(" + lockTypeKey + "_" + lockKey + ")");
+        } catch (final Exception e) {
+            LOGGER.warn("error releasing write lock on context map " + lockTypeKey + " context item " + lockKey, e);
+            throw new ContextException(
+                    "error releasing write lock on context map " + lockTypeKey + " context item " + lockKey, e);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.core.context.LockManager#shutdown()
+     */
+    @Override
+    public abstract void shutdown();
+
+    /**
+     * Get a reentrant read write lock from whatever locking mechanism is in use.
+     *
+     * @param lockId The unique ID of the lock.
+     * @return The lock
+     * @throws ContextException On errors getting a lock
+     */
+    protected abstract ReadWriteLock getReentrantReadWriteLock(String lockId) throws ContextException;
+
+    /**
+     * Get a lock for a context item in a context map.
+     *
+     * @param lockTypeKey The key of the map where the context item to lock is
+     * @param lockKey The key on the map to lock
+     * @param createMode if true, create a lock if it does not exist
+     * @return The lock
+     * @throws ContextException On errors getting the lock
+     */
+    private ReadWriteLock getLock(final String lockTypeKey, final String lockKey, final boolean createMode)
+            throws ContextException {
+        // Check if we have a lock type map for this lock type yet
+        if (!lockMaps.containsKey(lockTypeKey)) {
+            // Create a lock type map for the lock type
+            lockMaps.put(lockTypeKey, Collections.synchronizedMap(new HashMap<String, ReadWriteLock>()));
+        }
+
+        // Find or create a lock in the lock map
+        ReadWriteLock lock = lockMaps.get(lockTypeKey).get(lockKey);
+        if (lock != null) {
+            return lock;
+        }
+
+        // Should we create a lock?
+        if (!createMode) {
+            LOGGER.warn("error getting lock on context map " + lockTypeKey + " context item " + lockKey
+                    + ", lock does not exist");
+            throw new ContextException("error getting lock on context map " + lockTypeKey + " context item " + lockKey
+                    + ", lock does not exist");
+        }
+
+        try {
+            // Create the lock using the specialization of this abstract class
+            lock = getReentrantReadWriteLock(lockTypeKey + "_" + lockKey);
+
+            // Add the lock to the lock map
+            lockMaps.get(lockTypeKey).put(lockKey, lock);
+
+            if (LOGGER.isTraceEnabled()) {
+                LOGGER.trace("created lock " + lockTypeKey + "_" + lockKey);
+            }
+            return lock;
+        } catch (final Exception e) {
+            LOGGER.warn("error getting lock on context map " + lockTypeKey + " context item " + lockKey, e);
+            throw new ContextException("error getting lock on context map " + lockTypeKey + " context item " + lockKey,
+                    e);
+        }
+    }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/locking/LockManagerFactory.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/locking/LockManagerFactory.java
new file mode 100644
index 0000000..f3f4a62
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/locking/LockManagerFactory.java
@@ -0,0 +1,84 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context.impl.locking;
+
+import org.onap.policy.apex.context.ContextException;
+import org.onap.policy.apex.context.LockManager;
+import org.onap.policy.apex.context.parameters.LockManagerParameters;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.service.ParameterService;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * This class returns a {@link LockManager} for the particular type of locking mechanism that has been configured for
+ * use.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class LockManagerFactory {
+    // Get a reference to the logger
+    private static final XLogger LOGGER = XLoggerFactory.getXLogger(LockManagerFactory.class);
+
+    /**
+     * Return a {@link LockManager} for the particular type of locking mechanism configured for use.
+     *
+     * @param key The key for the lock manager
+     * @return a lock manager that can generate locks using some underlying mechanism
+     * @throws ContextException on errors in getting a lock manager
+     */
+    public LockManager createLockManager(final AxArtifactKey key) throws ContextException {
+        LOGGER.entry("Lock Manager factory, key=" + key);
+
+        final LockManagerParameters lockManagerParameters = ParameterService.getParameters(LockManagerParameters.class);
+
+        // Get the class for the lock manager using reflection
+        Object lockManagerObject = null;
+        final String pluginClass = lockManagerParameters.getPluginClass();
+        try {
+            lockManagerObject = Class.forName(pluginClass).newInstance();
+        } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
+            LOGGER.error(
+                    "Apex context lock manager class not found for context lock manager plugin \"" + pluginClass + "\"",
+                    e);
+            throw new ContextException(
+                    "Apex context lock manager class not found for context lock manager plugin \"" + pluginClass + "\"",
+                    e);
+        }
+
+        // Check the class is a lock manager
+        if (!(lockManagerObject instanceof LockManager)) {
+            LOGGER.error("Specified Apex context lock manager plugin class \"" + pluginClass
+                    + "\" does not implement the LockManager interface");
+            throw new ContextException("Specified Apex context lock manager plugin class \"" + pluginClass
+                    + "\" does not implement the LockManager interface");
+        }
+
+        // The context lock manager to return
+        final LockManager lockManager = (LockManager) lockManagerObject;
+
+        // Lock and load (OK sorry!!!) the lock manager
+        lockManager.init(key);
+
+        LOGGER.exit("Lock manager factory, key=" + key + ", selected lock manager of class " + lockManager.getClass());
+        return lockManager;
+    }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/locking/jvmlocal/JVMLocalLockManager.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/locking/jvmlocal/JVMLocalLockManager.java
new file mode 100644
index 0000000..5e71557
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/locking/jvmlocal/JVMLocalLockManager.java
@@ -0,0 +1,56 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context.impl.locking.jvmlocal;
+
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.onap.policy.apex.context.ContextException;
+import org.onap.policy.apex.context.impl.locking.AbstractLockManager;
+
+/**
+ * A lock manager that returns locks that have a range of just the local JVM. The implementation uses a Jav
+ * {@link ReentrantReadWriteLock} as the lock for context album items.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class JVMLocalLockManager extends AbstractLockManager {
+    /*
+     * (non-Javadoc)
+     *
+     * @see
+     * org.onap.policy.apex.core.context.impl.locking.AbstractLockManager#getReentrantReadWriteLock(java.lang.String)
+     */
+    @Override
+    public ReadWriteLock getReentrantReadWriteLock(final String lockId) throws ContextException {
+        return new ReentrantReadWriteLock();
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.core.context.LockManager#shutdown()
+     */
+    @Override
+    public void shutdown() {
+        // Nothing to do for this lock manager
+    }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/locking/jvmlocal/package-info.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/locking/jvmlocal/package-info.java
new file mode 100644
index 0000000..f1ac5cf
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/locking/jvmlocal/package-info.java
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+/**
+ * Provides the JVM local default context lock management mechanism for apex.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+
+package org.onap.policy.apex.context.impl.locking.jvmlocal;
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/locking/package-info.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/locking/package-info.java
new file mode 100644
index 0000000..1a46727
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/locking/package-info.java
@@ -0,0 +1,26 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+/**
+ * Provides an implementation of context album lock management that uses a lock management plugin to lock items items in
+ * Apex context albums. It also provides a default JVM local lock management plugin.
+ */
+
+package org.onap.policy.apex.context.impl.locking;
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/package-info.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/package-info.java
new file mode 100644
index 0000000..989827b
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/package-info.java
@@ -0,0 +1,28 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+/**
+ * Provides an implementation of APEX context schemas and APEX context albums. It provides default implementations of
+ * context schema handling and context album distribution, locking, and persistence.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+
+package org.onap.policy.apex.context.impl;
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/persistence/PersistorFactory.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/persistence/PersistorFactory.java
new file mode 100644
index 0000000..af6f922
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/persistence/PersistorFactory.java
@@ -0,0 +1,83 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context.impl.persistence;
+
+import org.onap.policy.apex.context.ContextException;
+import org.onap.policy.apex.context.Persistor;
+import org.onap.policy.apex.context.parameters.PersistorParameters;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.service.ParameterService;
+import org.onap.policy.apex.model.utilities.Assertions;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * This class returns a persistor for the particular type of persistor mechanism that has been configured for use.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class PersistorFactory {
+    // Get a reference to the logger
+    private static final XLogger LOGGER = XLoggerFactory.getXLogger(PersistorFactory.class);
+
+    /**
+     * Return a persistor for the persistence mechanism configured for use.
+     *
+     * @param key The key for the persistor
+     * @return a persistor
+     * @throws ContextException on invalid persistor types
+     */
+    public Persistor createPersistor(final AxArtifactKey key) throws ContextException {
+        LOGGER.entry("persistor factory, key=" + key);
+        Assertions.argumentNotNull(key, ContextException.class, "Parameter \"key\" may not be null");
+
+        final PersistorParameters persistorParameters = ParameterService.getParameters(PersistorParameters.class);
+
+        // Get the class for the persistor using reflection
+        Object persistorObject = null;
+        final String pluginClass = persistorParameters.getPluginClass();
+        try {
+            persistorObject = Class.forName(pluginClass).newInstance();
+        } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
+            LOGGER.error("Apex context persistor class not found for context persistor plugin \"" + pluginClass + "\"",
+                    e);
+            throw new ContextException(
+                    "Apex context persistor class not found for context persistor plugin \"" + pluginClass + "\"", e);
+        }
+
+        // Check the class is a persistor
+        if (!(persistorObject instanceof Persistor)) {
+            LOGGER.error("Specified Apex context persistor plugin class \"" + pluginClass
+                    + "\" does not implement the ContextDistributor interface");
+            throw new ContextException("Specified Apex context persistor plugin class \"" + pluginClass
+                    + "\" does not implement the ContextDistributor interface");
+        }
+
+        // The persistor to return
+        final Persistor persistor = (Persistor) persistorObject;
+
+        // Lock and load the persistor
+        persistor.init(key);
+
+        LOGGER.exit("Persistor factory, key=" + key + ", selected persistor of class " + persistor.getClass());
+        return persistor;
+    }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/persistence/ephemeral/EphemeralPersistor.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/persistence/ephemeral/EphemeralPersistor.java
new file mode 100644
index 0000000..b875978
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/persistence/ephemeral/EphemeralPersistor.java
@@ -0,0 +1,100 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context.impl.persistence.ephemeral;
+
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.onap.policy.apex.context.ContextException;
+import org.onap.policy.apex.context.Persistor;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+
+/**
+ * This class acts as an "in memory" persistor for a single JVM. It just initiates stubs the Persistor interface and
+ * does not persist anything.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class EphemeralPersistor implements Persistor {
+
+    // The key of this persistor
+    private AxArtifactKey key;
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.context.Persistor#init(org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey)
+     */
+    @Override
+    public void init(final AxArtifactKey persistorKey) throws ContextException {
+        this.key = persistorKey;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.context.Persistor#getKey()
+     */
+    @Override
+    public AxArtifactKey getKey() {
+        return key;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.core.context.Persistor#readContextItem(org.onap.policy.apex.core.basicmodel.concepts.
+     * AxReferenceKey, java.lang.Class)
+     */
+    @Override
+    public AxContextSchema readContextItem(final AxReferenceKey itemKey, final Class<?> contextItemClass) {
+        // Can't read from this persistor as nothing is persisted
+        return null;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.core.context.Persistor#readContextItems(org.onap.policy.apex.core.basicmodel.concepts.
+     * AxArtifactKey, java.lang.Class)
+     */
+    @Override
+    public Set<AxContextSchema> readContextItems(final AxArtifactKey ownerKey, final Class<?> contextItemClass)
+            throws ContextException {
+        // No reading from persistence on the Ephemeral persistor, return an empty set
+        return new TreeSet<>();
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see
+     * org.onap.policy.apex.core.context.Persistor#writeContextItem(org.onap.policy.apex.core.contextmodel.concepts.
+     * AxContextItem)
+     */
+    @Override
+    public Object writeContextItem(final Object contextItem) {
+        // No writing to persistence on the Ephemeral persistor
+        return contextItem;
+    }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/persistence/ephemeral/package-info.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/persistence/ephemeral/package-info.java
new file mode 100644
index 0000000..2d31d21
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/persistence/ephemeral/package-info.java
@@ -0,0 +1,28 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+/**
+ * Provides the JVM local default context persistence mechanism for APEX, which is in fact a dummy persistor that just
+ * stubs the Persistor interface and does not persist anything.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+
+package org.onap.policy.apex.context.impl.persistence.ephemeral;
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/persistence/package-info.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/persistence/package-info.java
new file mode 100644
index 0000000..d450dd8
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/persistence/package-info.java
@@ -0,0 +1,28 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+/**
+ * Provides an implementation of context album persistence that uses a persistence plugin to lock items items in APEX
+ * context albums. It also provides a default JVM local persistence plugin.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+
+package org.onap.policy.apex.context.impl.persistence;
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/AbstractSchemaHelper.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/AbstractSchemaHelper.java
new file mode 100644
index 0000000..83d1b6b
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/AbstractSchemaHelper.java
@@ -0,0 +1,169 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context.impl.schema;
+
+import java.lang.reflect.Constructor;
+
+import org.onap.policy.apex.context.ContextRuntimeException;
+import org.onap.policy.apex.context.SchemaHelper;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+import org.onap.policy.apex.model.utilities.Assertions;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * This class implements the {@link SchemaHelper} functionality that is common across all implementations. Schema
+ * helpers for specific schema mechanisms specialize this class.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public abstract class AbstractSchemaHelper implements SchemaHelper {
+    // Get a reference to the logger
+    private static final XLogger LOGGER = XLoggerFactory.getXLogger(AbstractSchemaHelper.class);
+
+    // The key of the user of this schema helper
+    private AxKey userKey = null;
+
+    // The schema of this schema helper
+    private AxContextSchema schema = null;
+
+    // The class of objects for this schema
+    private Class<?> schemaClass;
+
+    /**
+     * Sets the schema class for the schema, designed jots to be called by sub classes.
+     *
+     * @param schemaClass the Java class that is used to hold items of this schema
+     */
+    protected void setSchemaClass(final Class<?> schemaClass) {
+        this.schemaClass = schemaClass;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.context.SchemaHelper#init(org.onap.policy.apex.model.basicmodel.concepts.AxKey,
+     * org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema)
+     */
+    @Override
+    public void init(final AxKey incomingUserKey, final AxContextSchema incomingSchema) throws ContextRuntimeException {
+        Assertions.argumentNotNull(incomingUserKey, ContextRuntimeException.class, "incomingUserKey may not be null");
+        Assertions.argumentNotNull(incomingSchema, ContextRuntimeException.class, "incomingSchema may not be null");
+
+        this.userKey = incomingUserKey;
+        this.schema = incomingSchema;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.context.SchemaHelper#getKey()
+     */
+    @Override
+    public AxKey getUserKey() {
+        return userKey;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.context.SchemaHelper#getSchema()
+     */
+    @Override
+    public AxContextSchema getSchema() {
+        return schema;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.context.SchemaHelper#getSchemaClass()
+     */
+    @Override
+    public Class<?> getSchemaClass() {
+        return schemaClass;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.context.SchemaHelper#getSchemaObject()
+     */
+    @Override
+    public Object getSchemaObject() {
+        return null;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.context.SchemaHelper#createNewInstance()
+     */
+    @Override
+    public Object createNewInstance() {
+        if (schemaClass == null) {
+            final String returnString =
+                    userKey.getID() + ": could not create an instance, schema class for the schema is null";
+            LOGGER.warn(returnString);
+            throw new ContextRuntimeException(returnString);
+        }
+
+        try {
+            return schemaClass.newInstance();
+        } catch (final Exception e) {
+            final String returnString =
+                    userKey.getID() + ": could not create an instance of class \"" + schemaClass.getCanonicalName()
+                            + "\" using the default constructor \"" + schemaClass.getSimpleName() + "()\"";
+            LOGGER.warn(returnString, e);
+            throw new ContextRuntimeException(returnString, e);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.context.SchemaHelper#createNewInstance(java.lang.String)
+     */
+    @Override
+    public Object createNewInstance(final String stringValue) {
+        if (schemaClass == null) {
+            final String returnString =
+                    userKey.getID() + ": could not create an instance, schema class for the schema is null";
+            LOGGER.warn(returnString);
+            throw new ContextRuntimeException(returnString);
+        }
+
+        try {
+            // Find a string constructor
+            final Constructor<?> stringConstructor = schemaClass.getConstructor(String.class);
+
+            // Invoke the constructor
+            return stringConstructor.newInstance(stringValue);
+        } catch (final Exception e) {
+            final String returnString =
+                    userKey.getID() + ": could not create an instance of class \"" + schemaClass.getCanonicalName()
+                            + "\" using the string constructor \"" + schemaClass.getSimpleName() + "(String)\"";
+            LOGGER.warn(returnString, e);
+            throw new ContextRuntimeException(returnString);
+        }
+    }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/SchemaHelperFactory.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/SchemaHelperFactory.java
new file mode 100644
index 0000000..7252d37
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/SchemaHelperFactory.java
@@ -0,0 +1,119 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context.impl.schema;
+
+import org.onap.policy.apex.context.ContextRuntimeException;
+import org.onap.policy.apex.context.SchemaHelper;
+import org.onap.policy.apex.context.parameters.SchemaHelperParameters;
+import org.onap.policy.apex.context.parameters.SchemaParameters;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.service.ModelService;
+import org.onap.policy.apex.model.basicmodel.service.ParameterService;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchemas;
+import org.onap.policy.apex.model.utilities.Assertions;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * This class returns a {@link SchemaHelper} for the particular type of schema mechanism configured for use.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class SchemaHelperFactory {
+    // Get a reference to the logger
+    private static final XLogger LOGGER = XLoggerFactory.getXLogger(SchemaHelperFactory.class);
+
+    /**
+     * Return a {@link SchemaHelper} for the particular type of schema mechanism configured for use.
+     *
+     * @param owningEntityKey The key of the entity that owns the schema helper
+     * @param schemaKey The key of the schema the schema helper is operating on
+     * @return a lock schema that can handle translation of objects in a particular schema format
+     * @throws ContextRuntimeException the context runtime exception
+     */
+    public SchemaHelper createSchemaHelper(final AxKey owningEntityKey, final AxArtifactKey schemaKey)
+            throws ContextRuntimeException {
+        LOGGER.entry("schema helper factory, owningEntityKey=" + owningEntityKey);
+        Assertions.argumentNotNull(owningEntityKey, ContextRuntimeException.class,
+                "Parameter \"owningEntityKey\" may not be null");
+        Assertions.argumentNotNull(schemaKey, ContextRuntimeException.class, "Parameter \"schemaKey\" may not be null");
+
+        // Get the schema for items in the album
+        final AxContextSchema schema = ModelService.getModel(AxContextSchemas.class).get(schemaKey);
+        if (schema == null) {
+            final String resultString =
+                    "schema \"" + schemaKey.getID() + "\" for entity " + owningEntityKey.getID() + " does not exist";
+            LOGGER.warn(resultString);
+            throw new ContextRuntimeException(resultString);
+        }
+
+        // Get the schema class using the parameter service
+        final SchemaParameters schemaParameters = ParameterService.getParameters(SchemaParameters.class);
+        if (schemaParameters == null) {
+            final String resultString = "context schema parameters \"" + SchemaParameters.class.getCanonicalName()
+                    + "\" not found in parameter service";
+            LOGGER.warn(resultString);
+            throw new ContextRuntimeException(resultString);
+        }
+
+        // Get the class for the schema helper from the schema parameters
+        final SchemaHelperParameters schemaHelperParameters =
+                schemaParameters.getSchemaHelperParameters(schema.getSchemaFlavour());
+        if (schemaHelperParameters == null) {
+            final String resultString = "context schema helper parameters not found for context schema  \""
+                    + schema.getSchemaFlavour() + "\"";
+            LOGGER.warn(resultString);
+            throw new ContextRuntimeException(resultString);
+        }
+
+        // Get the class for the schema helper using reflection
+        Object schemaHelperObject = null;
+        final String pluginClass = schemaHelperParameters.getSchemaHelperPluginClass();
+        try {
+            schemaHelperObject = Class.forName(pluginClass).newInstance();
+        } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
+            final String resultString = "Apex context schema helper class not found for context schema helper plugin \""
+                    + pluginClass + "\"";
+            LOGGER.warn(resultString, e);
+            throw new ContextRuntimeException(resultString, e);
+        }
+
+        // Check the class is a schema helper
+        if (!(schemaHelperObject instanceof SchemaHelper)) {
+            final String resultString = "Specified Apex context schema helper plugin class \"" + pluginClass
+                    + "\" does not implement the SchemaHelper interface";
+            LOGGER.warn(resultString);
+            throw new ContextRuntimeException(resultString);
+        }
+
+        // The context schema helper to return
+        final SchemaHelper schemaHelper = (SchemaHelper) schemaHelperObject;
+
+        // Lock and load the schema helper
+        schemaHelper.init(owningEntityKey.getKey(), schema);
+
+        LOGGER.exit("Schema Helper factory, owningEntityKey=" + owningEntityKey + ", selected schema helper of class "
+                + schemaHelper.getClass());
+        return schemaHelper;
+    }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/java/JavaSchemaHelper.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/java/JavaSchemaHelper.java
new file mode 100644
index 0000000..b89efbf
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/java/JavaSchemaHelper.java
@@ -0,0 +1,214 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context.impl.schema.java;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+
+import java.lang.reflect.Constructor;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.onap.policy.apex.context.ContextRuntimeException;
+import org.onap.policy.apex.context.impl.schema.AbstractSchemaHelper;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+import org.onap.policy.apex.model.utilities.typeutils.TypeBuilder;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * This class implements translation to and from Apex distributed objects and Java objects when a Java schema is used.
+ * It creates schema items as Java objects and marshals and unmarshals these objects in various formats. All objects
+ * must be of the type of Java class defined in the schema.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class JavaSchemaHelper extends AbstractSchemaHelper {
+    // Get a reference to the logger
+    private static final XLogger LOGGER = XLoggerFactory.getXLogger(JavaSchemaHelper.class);
+
+    // This map defines the built in types in types in Java
+    // @formatter:off
+    private static final Map<String, Class<?>> BUILT_IN_MAP = new HashMap<>();
+    {
+        BUILT_IN_MAP.put("int",    Integer  .TYPE);
+        BUILT_IN_MAP.put("long",   Long     .TYPE);
+        BUILT_IN_MAP.put("double", Double   .TYPE);
+        BUILT_IN_MAP.put("float",  Float    .TYPE);
+        BUILT_IN_MAP.put("bool",   Boolean  .TYPE);
+        BUILT_IN_MAP.put("char",   Character.TYPE);
+        BUILT_IN_MAP.put("byte",   Byte     .TYPE);
+        BUILT_IN_MAP.put("void",   Void     .TYPE);
+        BUILT_IN_MAP.put("short",  Short    .TYPE);
+    }
+    // @formatter:on
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.context.impl.schema.AbstractSchemaHelper#init(org.onap.policy.apex.model.basicmodel.
+     * concepts. AxKey, org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema)
+     */
+    @Override
+    public void init(final AxKey userKey, final AxContextSchema schema) throws ContextRuntimeException {
+        super.init(userKey, schema);
+
+        final String javatype = schema.getSchema();
+        // For Java, the schema is the Java class canonical path
+
+        try {
+            setSchemaClass(TypeBuilder.getJavaTypeClass(schema.getSchema()));
+        } catch (final IllegalArgumentException e) {
+
+            String resultSting = userKey.getID() + ": class/type " + schema.getSchema() + " for context schema \""
+                    + schema.getID() + "\" not found.";
+            if (JavaSchemaHelper.BUILT_IN_MAP.get(javatype) != null) {
+                resultSting += " Primitive types are not supported. Use the appropriate Java boxing type instead.";
+            } else {
+                resultSting += " Check the class path of the JVM";
+            }
+            LOGGER.warn(resultSting);
+            throw new ContextRuntimeException(resultSting, e);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.context.SchemaHelper#createNewInstance(com.google.gson.JsonElement)
+     */
+    @Override
+    public Object createNewInstance(final JsonElement jsonElement) {
+        final String elementJsonString = new Gson().toJson(jsonElement);
+
+        return new Gson().fromJson(elementJsonString, this.getSchemaClass());
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.context.SchemaHelper#object2SchemaObject(java.lang.Object)
+     */
+    @Override
+    public Object unmarshal(final Object object) {
+        if (object == null) {
+            return null;
+        }
+
+        // If the object is an instance of the incoming object, carry on
+        if (object.getClass().equals(getSchemaClass())) {
+            return object;
+        }
+
+        // For numeric types, do a numeric conversion
+        if (Number.class.isAssignableFrom(getSchemaClass())) {
+            return numericConversion(object);
+        }
+
+        if (getSchemaClass().isAssignableFrom(object.getClass())) {
+            return object;
+        } else {
+            return stringConversion(object);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.context.SchemaHelper#schemaObject2Json(java.lang.Object)
+     */
+    @Override
+    public String marshal2Json(final Object schemaObject) {
+        if (schemaObject == null) {
+            return "null";
+        }
+
+        // Check the incoming object is of a correct class
+        if (getSchemaClass().isAssignableFrom(schemaObject.getClass())) {
+            // Use Gson to translate the object
+            return new Gson().toJson(schemaObject);
+        } else {
+            final String returnString = getUserKey().getID() + ": object \"" + schemaObject.toString()
+                    + "\" of class \"" + schemaObject.getClass().getCanonicalName() + "\" not compatible with class \""
+                    + getSchemaClass().getCanonicalName() + "\"";
+            LOGGER.warn(returnString);
+            throw new ContextRuntimeException(returnString);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.context.SchemaHelper#marshal2JsonElement(java.lang.Object)
+     */
+    @Override
+    public JsonElement marshal2JsonElement(final Object schemaObject) {
+        // Use Gson to marshal the schema object into a Json element to return
+        return new Gson().toJsonTree(schemaObject, getSchemaClass());
+    }
+
+    /**
+     * Do a numeric conversion between numeric types.
+     *
+     * @param object The incoming numeric object
+     * @return The converted object
+     */
+    private Object numericConversion(final Object object) {
+        // Check if the incoming object is a number, if not do a string conversion
+        if (object instanceof Number) {
+            if (getSchemaClass().isAssignableFrom(Byte.class)) {
+                return ((Number) object).byteValue();
+            } else if (getSchemaClass().isAssignableFrom(Integer.class)) {
+                return ((Number) object).intValue();
+            } else if (getSchemaClass().isAssignableFrom(Long.class)) {
+                return ((Number) object).longValue();
+            } else if (getSchemaClass().isAssignableFrom(Float.class)) {
+                return ((Number) object).floatValue();
+            } else if (getSchemaClass().isAssignableFrom(Double.class)) {
+                return ((Number) object).doubleValue();
+            }
+        }
+
+        // OK, we'll try and convert from a string representation of the incoming object
+        return stringConversion(object);
+    }
+
+    /**
+     * Do a string conversion to the class type.
+     *
+     * @param object The incoming numeric object
+     * @return The converted object
+     */
+    private Object stringConversion(final Object object) {
+        // OK, we'll try and convert from a string representation of the incoming object
+        try {
+            final Constructor<?> stringConstructor = getSchemaClass().getConstructor(String.class);
+            return stringConstructor.newInstance(object.toString());
+        } catch (final Exception e) {
+            final String returnString = getUserKey().getID() + ": object \"" + object.toString() + "\" of class \""
+                    + object.getClass().getCanonicalName() + "\" not compatible with class \""
+                    + getSchemaClass().getCanonicalName() + "\"";
+            LOGGER.warn(returnString);
+            throw new ContextRuntimeException(returnString);
+        }
+    }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/java/JavaSchemaHelperParameters.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/java/JavaSchemaHelperParameters.java
new file mode 100644
index 0000000..18339d8
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/java/JavaSchemaHelperParameters.java
@@ -0,0 +1,38 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context.impl.schema.java;
+
+import org.onap.policy.apex.context.parameters.SchemaHelperParameters;
+
+/**
+ * The Schema helper parameter class for the Java schema helper is an empty parameter class that acts as a placeholder.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class JavaSchemaHelperParameters extends SchemaHelperParameters {
+
+    /**
+     * The Constructor.
+     */
+    public JavaSchemaHelperParameters() {
+        this.setSchemaHelperPluginClass(JavaSchemaHelper.class.getCanonicalName());
+    }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/java/package-info.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/java/package-info.java
new file mode 100644
index 0000000..0529813
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/java/package-info.java
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+/**
+ * Provides the Java schema helper for APEX, which manages context items that are Java objects.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+
+package org.onap.policy.apex.context.impl.schema.java;
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/package-info.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/package-info.java
new file mode 100644
index 0000000..458a86a
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/package-info.java
@@ -0,0 +1,29 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+/**
+ * Provides an implementation of context schema handling that uses a schema helper plugin to manage schemas and to
+ * create, marshal, and unmarshal context items in various formats for APEX context. It also provides a default java
+ * schema handler plugin.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+
+package org.onap.policy.apex.context.impl.schema;
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/monitoring/ContextMonitor.java b/context/context-management/src/main/java/org/onap/policy/apex/context/monitoring/ContextMonitor.java
new file mode 100644
index 0000000..8e34ecb
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/monitoring/ContextMonitor.java
@@ -0,0 +1,210 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context.monitoring;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * This class is used to monitor context creates, deletes, gets, sets, locks and unlocks on context items in Apex
+ * context albums.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ContextMonitor {
+    // Logger for this class
+    private static final XLogger LOGGER = XLoggerFactory.getXLogger(ContextMonitor.class);
+
+    /**
+     * Monitor an initiation on a context item.
+     *
+     * @param albumKey The item album
+     * @param schemaKey The item schema
+     * @param name The name of the item
+     * @param value The value of the item
+     */
+    public void monitorInit(final AxArtifactKey albumKey, final AxArtifactKey schemaKey, final String name,
+            final Object value) {
+        LOGGER.trace(monitor("INIT", null, albumKey, schemaKey, name, value));
+    }
+
+    /**
+     * Monitor an initiation on a context item.
+     *
+     * @param albumKey The item album
+     * @param schemaKey The item schema
+     * @param name The name of the item
+     * @param value The value of the item
+     * @param userArtifactStack the keys of the artifacts using the context map at the moment
+     */
+    public void monitorInit(final AxArtifactKey albumKey, final AxArtifactKey schemaKey, final String name,
+            final Object value, final AxConcept[] userArtifactStack) {
+        LOGGER.trace(monitor("INIT", userArtifactStack, albumKey, schemaKey, name, value));
+    }
+
+    /**
+     * Monitor a deletion on a context item.
+     *
+     * @param albumKey The item album
+     * @param schemaKey The item schema
+     * @param name The name of the item
+     * @param value The value of the item
+     * @param userArtifactStack the keys of the artifacts using the context map at the moment
+     */
+    public void monitorDelete(final AxArtifactKey albumKey, final AxArtifactKey schemaKey, final String name,
+            final Object value, final AxConcept[] userArtifactStack) {
+        LOGGER.trace(monitor("DEL", userArtifactStack, albumKey, schemaKey, name, value));
+    }
+
+    /**
+     * Monitor get on a context item.
+     *
+     * @param albumKey The item album
+     * @param schemaKey The item schema
+     * @param name The name of the item
+     * @param value The value of the item
+     * @param userArtifactStack the keys of the artifacts using the context map at the moment
+     */
+    public void monitorGet(final AxArtifactKey albumKey, final AxArtifactKey schemaKey, final String name,
+            final Object value, final AxConcept[] userArtifactStack) {
+        LOGGER.trace(monitor("GET", userArtifactStack, albumKey, schemaKey, name, value));
+    }
+
+    /**
+     * Monitor set on a context item.
+     *
+     * @param albumKey The item album
+     * @param schemaKey The item schema
+     * @param name The name of the item
+     * @param value The value of the item
+     * @param userArtifactStack the keys of the artifacts using the context map at the moment
+     */
+    public void monitorSet(final AxArtifactKey albumKey, final AxArtifactKey schemaKey, final String name,
+            final Object value, final AxConcept[] userArtifactStack) {
+        LOGGER.trace(monitor("SET", userArtifactStack, albumKey, schemaKey, name, value));
+    }
+
+    /**
+     * Monitor a read lock on a key.
+     *
+     * @param albumKey The item album
+     * @param schemaKey The item schema
+     * @param name The name of the item
+     * @param userArtifactStack the keys of the artifacts using the context map at the moment
+     */
+    public void monitorReadLock(final AxArtifactKey albumKey, final AxArtifactKey schemaKey, final String name,
+            final AxConcept[] userArtifactStack) {
+        LOGGER.trace(monitor("READLOCK", userArtifactStack, albumKey, schemaKey, name, null));
+    }
+
+    /**
+     * Monitor a write lock on a key.
+     *
+     * @param albumKey The item album
+     * @param schemaKey The item schema
+     * @param name The name of the item
+     * @param userArtifactStack the keys of the artifacts using the context map at the moment
+     */
+    public void monitorWriteLock(final AxArtifactKey albumKey, final AxArtifactKey schemaKey, final String name,
+            final AxConcept[] userArtifactStack) {
+        LOGGER.trace(monitor("WRITELOCK", userArtifactStack, albumKey, schemaKey, name, null));
+    }
+
+    /**
+     * Monitor a read unlock on a key.
+     *
+     * @param albumKey The item album
+     * @param schemaKey The item schema
+     * @param name The name of the item
+     * @param userArtifactStack the keys of the artifacts using the context map at the moment
+     */
+    public void monitorReadUnlock(final AxArtifactKey albumKey, final AxArtifactKey schemaKey, final String name,
+            final AxConcept[] userArtifactStack) {
+        LOGGER.trace(monitor("READUNLOCK", userArtifactStack, albumKey, schemaKey, name, null));
+    }
+
+    /**
+     * Monitor a write unlock on a key.
+     *
+     * @param albumKey The item album
+     * @param schemaKey The item schema
+     * @param name The name of the item
+     * @param userArtifactStack the keys of the artifacts using the context map at the moment
+     */
+    public void monitorWriteUnlock(final AxArtifactKey albumKey, final AxArtifactKey schemaKey, final String name,
+            final AxConcept[] userArtifactStack) {
+        LOGGER.trace(monitor("WRITEUNLOCK", userArtifactStack, albumKey, schemaKey, name, null));
+    }
+
+    /**
+     * Monitor the user artifact stack.
+     *
+     * @param preamble the preamble
+     * @param userArtifactStack The user stack to print
+     * @param albumKey the album key
+     * @param schemaKey the schema key
+     * @param name the name
+     * @param value the value
+     * @return the string
+     */
+    private String monitor(final String preamble, final AxConcept[] userArtifactStack, final AxArtifactKey albumKey,
+            final AxArtifactKey schemaKey, final String name, final Object value) {
+        final StringBuilder builder = new StringBuilder();
+
+        builder.append(preamble);
+        builder.append(",[");
+
+        if (userArtifactStack != null) {
+            boolean first = true;
+            for (final AxConcept stackKey : userArtifactStack) {
+                if (first) {
+                    first = false;
+                } else {
+                    builder.append(',');
+                }
+                if (stackKey instanceof AxArtifactKey) {
+                    builder.append(((AxArtifactKey) stackKey).getID());
+                } else if (stackKey instanceof AxReferenceKey) {
+                    builder.append(((AxReferenceKey) stackKey).getID());
+                } else {
+                    builder.append(stackKey.toString());
+                }
+            }
+        }
+        builder.append("],");
+
+        builder.append(albumKey.getID());
+        builder.append(',');
+        builder.append(schemaKey.getID());
+        builder.append(',');
+        builder.append(name);
+
+        if (value != null) {
+            builder.append(',');
+            builder.append(value.toString());
+        }
+
+        return builder.toString();
+    }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/monitoring/package-info.java b/context/context-management/src/main/java/org/onap/policy/apex/context/monitoring/package-info.java
new file mode 100644
index 0000000..2f8ac82
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/monitoring/package-info.java
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+/**
+ * Monitors all creation, deletion, get, set, lock, and unlock operations on items in APEX context albums.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+
+package org.onap.policy.apex.context.monitoring;
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/package-info.java b/context/context-management/src/main/java/org/onap/policy/apex/context/package-info.java
new file mode 100644
index 0000000..8707ae3
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/package-info.java
@@ -0,0 +1,29 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+/**
+ * Provides the context handling for APEX. It provides the infrastructure and generic implementation for context schemas
+ * and context albums. Schema handlers and context album handlers are implemented as plugins that implement interfaces
+ * defined in this package.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+
+package org.onap.policy.apex.context;
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/ContextParameters.java b/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/ContextParameters.java
new file mode 100644
index 0000000..e50cc60
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/ContextParameters.java
@@ -0,0 +1,146 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context.parameters;
+
+import org.onap.policy.apex.model.basicmodel.service.AbstractParameters;
+import org.onap.policy.apex.model.basicmodel.service.ParameterService;
+
+/**
+ * Bean class to hold parameters for context handling in Apex. This class contains all the context parameters for schema
+ * handling, distribution, locking, and persistence of context albums.
+ * <p>
+ * The following parameters are defined:
+ * <ol>
+ * <li>flushPeriod: Context is flushed to any persistor plugin that is defined periodically, and the period for flushing
+ * is the flush period.
+ * <li>distributorParameters: The parameters (a {@link distributorParameters} instance) for the distributor plugin that
+ * is being used for context album distribution
+ * <li>schemaParameters: The parameters (a {@link SchemaParameters} instance) for the schema plugin that is being used
+ * for context album schemas
+ * <li>lockManagerParameters: The parameters (a {@link LockManagerParameters} instance) for the locking mechanism plugin
+ * that is being used for context album locking
+ * <li>persistorParameters: The parameters (a {@link PersistorParameters} instance) for the persistence plugin that is
+ * being used for context album persistence
+ * </ol>
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ContextParameters extends AbstractParameters {
+    // @formatter:off
+    // Plugin Parameters
+    private DistributorParameters distributorParameters = new DistributorParameters();
+    private SchemaParameters      schemaParameters      = new SchemaParameters();
+    private LockManagerParameters lockManagerParameters = new LockManagerParameters();
+    private PersistorParameters   persistorParameters   = new PersistorParameters();
+    // @formatter:on
+
+    /**
+     * Constructor to create a context parameters instance and register the instance with the parameter service.
+     */
+    public ContextParameters() {
+        super(ContextParameters.class.getCanonicalName());
+        ParameterService.registerParameters(ContextParameters.class, this);
+    }
+
+    /**
+     * Gets the distributor parameters.
+     *
+     * @return the distributor parameters
+     */
+    public DistributorParameters getDistributorParameters() {
+        return distributorParameters;
+    }
+
+    /**
+     * Sets the distributor parameters.
+     *
+     * @param distributorParameters the distributor parameters
+     */
+    public void setDistributorParameters(final DistributorParameters distributorParameters) {
+        this.distributorParameters = distributorParameters;
+    }
+
+    /**
+     * Gets the schema parameters.
+     *
+     * @return the schema parameters
+     */
+    public SchemaParameters getSchemaParameters() {
+        return schemaParameters;
+    }
+
+    /**
+     * Sets the schema parameters.
+     *
+     * @param schemaParameters the schema parameters
+     */
+    public void setSchemaParameters(final SchemaParameters schemaParameters) {
+        this.schemaParameters = schemaParameters;
+    }
+
+    /**
+     * Gets the lock manager parameters.
+     *
+     * @return the lock manager parameters
+     */
+    public LockManagerParameters getLockManagerParameters() {
+        return lockManagerParameters;
+    }
+
+    /**
+     * Sets the lock manager parameters.
+     *
+     * @param lockManagerParameters the lock manager parameters
+     */
+    public void setLockManagerParameters(final LockManagerParameters lockManagerParameters) {
+        this.lockManagerParameters = lockManagerParameters;
+    }
+
+    /**
+     * Gets the persistor parameters.
+     *
+     * @return the persistor parameters
+     */
+    public PersistorParameters getPersistorParameters() {
+        return persistorParameters;
+    }
+
+    /**
+     * Sets the persistor parameters.
+     *
+     * @param persistorParameters the persistor parameters
+     */
+    public void setPersistorParameters(final PersistorParameters persistorParameters) {
+        this.persistorParameters = persistorParameters;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.model.basicmodel.service.AbstractParameters#toString()
+     */
+    @Override
+    public String toString() {
+        return "ContextParameters [distributorParameters=" + distributorParameters + ", schemaParameters="
+                + schemaParameters + ", lockManagerParameters=" + lockManagerParameters + ", persistorParameters="
+                + persistorParameters + "]";
+    }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/DistributorParameters.java b/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/DistributorParameters.java
new file mode 100644
index 0000000..147e4eb
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/DistributorParameters.java
@@ -0,0 +1,85 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context.parameters;
+
+import org.onap.policy.apex.model.basicmodel.service.AbstractParameters;
+import org.onap.policy.apex.model.basicmodel.service.ParameterService;
+
+/**
+ * An empty distributor parameter class that may be specialized by context distributor plugins that require plugin
+ * specific parameters. The class defines the default distributor plugin as the JVM local distributor.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class DistributorParameters extends AbstractParameters {
+    /** The default distributor makes context albums available to all threads in a single JVM. */
+    public static final String DEFAULT_DISTRIBUTOR_PLUGIN_CLASS =
+            "org.onap.policy.apex.context.impl.distribution.jvmlocal.JVMLocalDistributor";
+
+    // Plugin class names
+    private String pluginClass = DEFAULT_DISTRIBUTOR_PLUGIN_CLASS;
+
+    /**
+     * Constructor to create a distributor parameters instance and register the instance with the parameter service.
+     */
+    public DistributorParameters() {
+        super(DistributorParameters.class.getCanonicalName());
+        ParameterService.registerParameters(DistributorParameters.class, this);
+    }
+
+    /**
+     * Constructor to create a distributor parameters instance with the name of a sub class of this class and register
+     * the instance with the parameter service.
+     *
+     * @param parameterClassName the class name of a sub class of this class
+     */
+    public DistributorParameters(final String parameterClassName) {
+        super(parameterClassName);
+    }
+
+    /**
+     * Gets the plugin class.
+     *
+     * @return the plugin class
+     */
+    public String getPluginClass() {
+        return pluginClass;
+    }
+
+    /**
+     * Sets the plugin class.
+     *
+     * @param pluginClass the plugin class
+     */
+    public void setPluginClass(final String pluginClass) {
+        this.pluginClass = pluginClass;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.model.basicmodel.service.AbstractParameters#toString()
+     */
+    @Override
+    public String toString() {
+        return "DistributorParameters [pluginClass=" + pluginClass + "]";
+    }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/LockManagerParameters.java b/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/LockManagerParameters.java
new file mode 100644
index 0000000..93e4223
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/LockManagerParameters.java
@@ -0,0 +1,85 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context.parameters;
+
+import org.onap.policy.apex.model.basicmodel.service.AbstractParameters;
+import org.onap.policy.apex.model.basicmodel.service.ParameterService;
+
+/**
+ * An empty lock manager parameter class that may be specialized by context lock manager plugins that require plugin
+ * specific parameters. The class defines the default lock manager plugin as the JVM local lock manager.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class LockManagerParameters extends AbstractParameters {
+    /** The default lock manager can lock context album instance across all threads in a single JVM. */
+    public static final String DEFAULT_LOCK_MANAGER_PLUGIN_CLASS =
+            "org.onap.policy.apex.context.impl.locking.jvmlocal.JVMLocalLockManager";
+
+    // Plugin class names
+    private String pluginClass = DEFAULT_LOCK_MANAGER_PLUGIN_CLASS;
+
+    /**
+     * Constructor to create a lock manager parameters instance and register the instance with the parameter service.
+     */
+    public LockManagerParameters() {
+        super(LockManagerParameters.class.getCanonicalName());
+        ParameterService.registerParameters(LockManagerParameters.class, this);
+    }
+
+    /**
+     * Constructor to create a lock manager parameters instance with the name of a sub class of this class and register
+     * the instance with the parameter service.
+     *
+     * @param parameterClassName the class name of a sub class of this class
+     */
+    public LockManagerParameters(final String parameterClassName) {
+        super(parameterClassName);
+    }
+
+    /**
+     * Gets the plugin class.
+     *
+     * @return the plugin class
+     */
+    public String getPluginClass() {
+        return pluginClass;
+    }
+
+    /**
+     * Sets the plugin class.
+     *
+     * @param pluginClass the plugin class
+     */
+    public void setPluginClass(final String pluginClass) {
+        this.pluginClass = pluginClass;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.model.basicmodel.service.AbstractParameters#toString()
+     */
+    @Override
+    public String toString() {
+        return "LockManagerParameters [pluginClass=" + pluginClass + "]";
+    }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/PersistorParameters.java b/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/PersistorParameters.java
new file mode 100644
index 0000000..c9b0d85
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/PersistorParameters.java
@@ -0,0 +1,120 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context.parameters;
+
+import org.onap.policy.apex.model.basicmodel.service.AbstractParameters;
+import org.onap.policy.apex.model.basicmodel.service.ParameterService;
+
+/**
+ * A persistor parameter class that may be specialized by context persistor plugins that require plugin specific
+ * parameters.
+ * <p>
+ * The following parameters are defined:
+ * <ol>
+ * <li>pluginClass: the persistor plugin as the JVM local dummy ephemeral persistor
+ * <li>flushPeriod: Context is flushed to any persistor plugin that is defined periodically, and the period for flushing
+ * is the flush period.
+ * </ol>
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class PersistorParameters extends AbstractParameters {
+    /** The default persistor is a dummy persistor that stubs the Persistor interface. */
+    public static final String DEFAULT_PERSISTOR_PLUGIN_CLASS =
+            "org.onap.policy.apex.context.impl.persistence.ephemeral.EphemeralPersistor";
+
+    /** Default periodic flushing interval, 5 minutes in milliseconds. */
+    public static final long DEFAULT_FLUSH_PERIOD = 300000;
+
+    // Plugin class names
+    private String pluginClass = DEFAULT_PERSISTOR_PLUGIN_CLASS;
+
+    // Parameters for flushing
+    private long flushPeriod = DEFAULT_FLUSH_PERIOD;
+
+    /**
+     * Constructor to create a persistor parameters instance and register the instance with the parameter service.
+     */
+    public PersistorParameters() {
+        super(PersistorParameters.class.getCanonicalName());
+        ParameterService.registerParameters(PersistorParameters.class, this);
+    }
+
+    /**
+     * Constructor to create a persistor parameters instance with the name of a sub class of this class and register the
+     * instance with the parameter service.
+     *
+     * @param parameterClassName the class name of a sub class of this class
+     */
+    public PersistorParameters(final String parameterClassName) {
+        super(parameterClassName);
+    }
+
+    /**
+     * Gets the plugin class.
+     *
+     * @return the plugin class
+     */
+    public String getPluginClass() {
+        return pluginClass;
+    }
+
+    /**
+     * Sets the plugin class.
+     *
+     * @param pluginClass the plugin class
+     */
+    public void setPluginClass(final String pluginClass) {
+        this.pluginClass = pluginClass;
+    }
+
+    /**
+     * Gets the flush period in milliseconds.
+     *
+     * @return the flush period
+     */
+    public long getFlushPeriod() {
+        return flushPeriod;
+    }
+
+    /**
+     * Sets the flush period in milliseconds.
+     *
+     * @param flushPeriod the flush period
+     */
+    public void setFlushPeriod(final long flushPeriod) {
+        if (flushPeriod <= 0) {
+            this.flushPeriod = DEFAULT_FLUSH_PERIOD;
+        } else {
+            this.flushPeriod = flushPeriod;
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.model.basicmodel.service.AbstractParameters#toString()
+     */
+    @Override
+    public String toString() {
+        return "PersistorParameters [pluginClass=" + pluginClass + ", flushPeriod=" + flushPeriod + "]";
+    }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/SchemaHelperParameters.java b/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/SchemaHelperParameters.java
new file mode 100644
index 0000000..9ccd431
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/SchemaHelperParameters.java
@@ -0,0 +1,81 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context.parameters;
+
+import org.onap.policy.apex.model.basicmodel.service.AbstractParameters;
+import org.onap.policy.apex.model.basicmodel.service.ParameterService;
+
+/**
+ * An empty schema helper parameter class that may be specialized by context schema helper plugins that require plugin
+ * specific parameters.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class SchemaHelperParameters extends AbstractParameters {
+    // Schema helper plugin class for the schema
+    private String schemaHelperPluginClass;
+
+    /**
+     * Constructor to create a schema helper parameters instance and register the instance with the parameter service.
+     */
+    public SchemaHelperParameters() {
+        super(SchemaHelperParameters.class.getCanonicalName());
+        ParameterService.registerParameters(SchemaHelperParameters.class, this);
+    }
+
+    /**
+     * Constructor to create a schema helper parameters instance with the name of a sub class of this class and register
+     * the instance with the parameter service.
+     *
+     * @param parameterClassName the class name of a sub class of this class
+     */
+    public SchemaHelperParameters(final String parameterClassName) {
+        super(parameterClassName);
+    }
+
+    /**
+     * Gets the schema helper plugin class.
+     *
+     * @return the schema helper plugin class
+     */
+    public String getSchemaHelperPluginClass() {
+        return schemaHelperPluginClass;
+    }
+
+    /**
+     * Sets the schema helper plugin class.
+     *
+     * @param pluginClass the schema helper plugin class
+     */
+    public void setSchemaHelperPluginClass(final String pluginClass) {
+        schemaHelperPluginClass = pluginClass;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.model.basicmodel.service.AbstractParameters#toString()
+     */
+    @Override
+    public String toString() {
+        return "SchemaHelperParameters [schemaHelperPluginClass=" + schemaHelperPluginClass + "]";
+    }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/SchemaParameters.java b/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/SchemaParameters.java
new file mode 100644
index 0000000..858a6a3
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/SchemaParameters.java
@@ -0,0 +1,87 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context.parameters;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.onap.policy.apex.context.impl.schema.java.JavaSchemaHelperParameters;
+import org.onap.policy.apex.model.basicmodel.service.AbstractParameters;
+import org.onap.policy.apex.model.basicmodel.service.ParameterService;
+
+/**
+ * Bean class holding schema parameters for schemas and their helpers. As more than one schema can be used in Apex
+ * simultaneously, this class is used to hold the schemas that are defined in a given Apex system and to get the schema
+ * helper plugin parameters {@link SchemaHelperParameters} for each schema.
+ * <p>
+ * The default {@code Java} schema is always defined and its parameters are held in a {@link JavaSchemaHelperParameters}
+ * instance.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class SchemaParameters extends AbstractParameters {
+    /** The Java schema flavour is always available for use. */
+    public static final String DEFAULT_SCHEMA_FLAVOUR = "Java";
+
+    // A map of parameters for executors of various logic types
+    private Map<String, SchemaHelperParameters> schemaHelperParameterMap;
+
+    /**
+     * Constructor to create a distributor parameters instance and register the instance with the parameter service.
+     */
+    public SchemaParameters() {
+        super(SchemaParameters.class.getCanonicalName());
+        ParameterService.registerParameters(SchemaParameters.class, this);
+
+        schemaHelperParameterMap = new TreeMap<>();
+
+        // The default schema helper
+        schemaHelperParameterMap.put(DEFAULT_SCHEMA_FLAVOUR, new JavaSchemaHelperParameters());
+    }
+
+    /**
+     * Gets a map of the schemas and schema helper parameters that are defined.
+     *
+     * @return the schema helper parameter map
+     */
+    public Map<String, SchemaHelperParameters> getSchemaHelperParameterMap() {
+        return schemaHelperParameterMap;
+    }
+
+    /**
+     * Sets the map of the schemas and schema helper parameters.
+     *
+     * @param schemaHelperParameterMap the schema helper parameter map
+     */
+    public void setSchemaHelperParameterMap(final Map<String, SchemaHelperParameters> schemaHelperParameterMap) {
+        this.schemaHelperParameterMap = schemaHelperParameterMap;
+    }
+
+    /**
+     * Gets the schema helper parameters for a given context schema flavour.
+     *
+     * @param schemaFlavour the schema flavour for which to get the schema helper parameters
+     * @return the schema helper parameters for the given schema flavour
+     */
+    public SchemaHelperParameters getSchemaHelperParameters(final String schemaFlavour) {
+        return schemaHelperParameterMap.get(schemaFlavour);
+    }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/package-info.java b/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/package-info.java
new file mode 100644
index 0000000..52a4270
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/package-info.java
@@ -0,0 +1,28 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+/**
+ * Holds the definitions of generic parameters for schema helpers, distributors, lock managers, and persistors in APEX.
+ * All the parameter definitions can be specialized to provide parameters to APEX plugins.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+
+package org.onap.policy.apex.context.parameters;
diff --git a/context/context-management/src/test/java/org/onap/policy/apex/context/impl/schema/java/TestInstanceCreation.java b/context/context-management/src/test/java/org/onap/policy/apex/context/impl/schema/java/TestInstanceCreation.java
new file mode 100644
index 0000000..9c2c685
--- /dev/null
+++ b/context/context-management/src/test/java/org/onap/policy/apex/context/impl/schema/java/TestInstanceCreation.java
@@ -0,0 +1,96 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context.impl.schema.java;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.policy.apex.context.SchemaHelper;
+import org.onap.policy.apex.context.impl.schema.SchemaHelperFactory;
+import org.onap.policy.apex.context.parameters.SchemaParameters;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.service.ModelService;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchemas;
+
+/**
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ * @version
+ */
+public class TestInstanceCreation {
+    private final AxKey testKey = new AxArtifactKey("AvroTest", "0.0.1");
+    private AxContextSchemas schemas;
+
+    @Before
+    public void initTest() {
+        schemas = new AxContextSchemas(new AxArtifactKey("AvroSchemas", "0.0.1"));
+        ModelService.registerModel(AxContextSchemas.class, schemas);
+        new SchemaParameters();
+    }
+
+    @Test
+    public void testNullEncoding() {
+        final AxContextSchema javaBooleanSchema =
+                new AxContextSchema(new AxArtifactKey("Boolean", "0.0.1"), "Java", "java.lang.Boolean");
+        final AxContextSchema javaLongSchema =
+                new AxContextSchema(new AxArtifactKey("Long", "0.0.1"), "Java", "java.lang.Long");
+        final AxContextSchema javaStringSchema =
+                new AxContextSchema(new AxArtifactKey("String", "0.0.1"), "Java", "java.lang.String");
+
+        schemas.getSchemasMap().put(javaBooleanSchema.getKey(), javaBooleanSchema);
+        schemas.getSchemasMap().put(javaLongSchema.getKey(), javaLongSchema);
+        schemas.getSchemasMap().put(javaStringSchema.getKey(), javaStringSchema);
+
+        final SchemaHelper schemaHelper0 =
+                new SchemaHelperFactory().createSchemaHelper(testKey, javaBooleanSchema.getKey());
+        final SchemaHelper schemaHelper1 =
+                new SchemaHelperFactory().createSchemaHelper(testKey, javaLongSchema.getKey());
+        final SchemaHelper schemaHelper2 =
+                new SchemaHelperFactory().createSchemaHelper(testKey, javaStringSchema.getKey());
+
+        try {
+            schemaHelper0.createNewInstance();
+            fail("this test should throw an exception here");
+        } catch (final Exception e) {
+            assertEquals(
+                    "AvroTest:0.0.1: could not create an instance of class \"java.lang.Boolean\" using the default constructor \"Boolean()\"",
+                    e.getMessage());
+        }
+        assertEquals(true, schemaHelper0.createNewInstance("true"));
+
+
+        try {
+            schemaHelper1.createNewInstance();
+            fail("this test should throw an exception here");
+        } catch (final Exception e) {
+            assertEquals(
+                    "AvroTest:0.0.1: could not create an instance of class \"java.lang.Long\" using the default constructor \"Long()\"",
+                    e.getMessage());
+        }
+        assertEquals(65536L, schemaHelper1.createNewInstance("65536"));
+
+        assertEquals("", schemaHelper2.createNewInstance());
+        assertEquals("true", schemaHelper2.createNewInstance("true"));
+    }
+}
diff --git a/context/context-management/src/test/resources/logback-test.xml b/context/context-management/src/test/resources/logback-test.xml
new file mode 100644
index 0000000..51398da
--- /dev/null
+++ b/context/context-management/src/test/resources/logback-test.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ============LICENSE_START=======================================================
+   Copyright (C) 2016-2018 Ericsson. 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.
+  
+  SPDX-License-Identifier: Apache-2.0
+  ============LICENSE_END=========================================================
+-->
+
+<configuration>
+
+    <contextName>Apex</contextName>
+    <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
+    <property name="LOG_DIR" value="${java.io.tmpdir}/apex_logging/" />
+
+	<!-- USE FOR STD OUT ONLY -->
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <Pattern>%d %contextName [%t] %level %logger{36} - %msg%n</Pattern>
+        </encoder>
+    </appender>
+
+    <root level="ERROR">
+        <appender-ref ref="STDOUT" />
+    </root>
+
+    <logger name="org.infinispan" level="ERROR" additivity="false">
+        <appender-ref ref="STDOUT" />
+    </logger>
+
+    <logger name="org.apache.zookeeper.ClientCnxn" level="OFF" additivity="false">
+        <appender-ref ref="STDOUT" />
+    </logger>
+
+    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
+        <file>${LOG_DIR}/apex.log</file>
+        <encoder>
+            <pattern>%d %-5relative [procId=${processId}] [%thread] %-5level
+                %logger{26} - %msg %n %ex{full}</pattern>
+        </encoder>
+    </appender>
+
+    <appender name="CTXT_FILE" class="ch.qos.logback.core.FileAppender">
+        <file>${LOG_DIR}/apex_ctxt.log</file>
+        <encoder>
+            <pattern>%d %-5relative [procId=${processId}] [%thread] %-5level
+                %logger{26} - %msg %n %ex{full}</pattern>
+        </encoder>
+    </appender>
+
+    <logger name="org.onap.policy.apex.core.context.impl.monitoring" level="ERROR" additivity="false">
+        <appender-ref ref="CTXT_FILE" />
+    </logger>
+
+    <logger name="org.onap.policy.apex.core.context" level="TRACE" additivity="false">
+        <appender-ref ref="STDOUT" />
+    </logger>
+</configuration>