Adding policy-model, model-api & engine-model

Change-Id: I56702b8f0953457d493f894d155b2a6ddc87b10c
Issue-ID: POLICY-856
Signed-off-by: waqas.ikram <waqas.ikram@ericsson.com>
diff --git a/model/model-api/pom.xml b/model/model-api/pom.xml
new file mode 100644
index 0000000..3fd4b27
--- /dev/null
+++ b/model/model-api/pom.xml
@@ -0,0 +1,40 @@
+<!--
+  ============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.model</groupId>
+        <artifactId>model</artifactId>
+        <version>2.0.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>model-api</artifactId>
+    <name>${project.artifactId}</name>
+    <description>APIs for editing Apex models</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>policy-model</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file
diff --git a/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/ApexAPIResult.java b/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/ApexAPIResult.java
new file mode 100644
index 0000000..2e4328f
--- /dev/null
+++ b/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/ApexAPIResult.java
@@ -0,0 +1,284 @@
+/*-
+ * ============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.model.modelapi;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlEnum;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * The Class ApexEditorAPIResult return the result of and messages from all model API method calls
+ * on the {@link ApexModel} API.
+ */
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class ApexAPIResult {
+
+    /**
+     * This enumeration is used to represent the result status of a call on the {@link ApexModel}
+     * API.
+     */
+    @XmlEnum(value = String.class)
+    public enum RESULT {
+        /** The method call succeeded. */
+        SUCCESS,
+        /** The method call succeeded and all operations are now completed. */
+        FINISHED,
+        /** The method call for a create operation failed because the concept already exists. */
+        CONCEPT_EXISTS,
+        /**
+         * The method call for a create operation failed because multiple concepts already exists.
+         */
+        MULTIPLE_CONCEPTS_EXIST,
+        /** The method call on a concept failed because the referenced concept does not exist. */
+        CONCEPT_DOES_NOT_EXIST,
+        /** The method call failed because no action was specified on the method call. */
+        NO_ACTION_SPECIFIED,
+        /**
+         * The method call failed because of a structural error, a missing reference, or other error
+         * on the model.
+         */
+        FAILED,
+        /**
+         * The method call failed for another reason such as the method call is not implemented yet
+         * on the concept on which it was called.
+         */
+        OTHER_ERROR
+    }
+
+    private RESULT result;
+    private List<String> messages = new ArrayList<>();
+
+    /**
+     * The Default Constructor creates a result for a successful operation with no messages.
+     */
+    public ApexAPIResult() {
+        result = RESULT.SUCCESS;
+    }
+
+    /**
+     * This Constructor creates a result with the given result status with no messages.
+     *
+     * @param result the result status to use on this result
+     */
+    public ApexAPIResult(final RESULT result) {
+        this.result = result;
+    }
+
+    /**
+     * This Constructor creates a result with the given result status and message.
+     *
+     * @param result the result status to use on this result
+     * @param message the message to return with the result
+     */
+    public ApexAPIResult(final RESULT result, final String message) {
+        this.result = result;
+        addMessage(message);
+    }
+
+    /**
+     * This Constructor creates a result with the given result status and {@link Throwable} object
+     * such as an exception. The message and stack trace from the {@link Throwable} object are added
+     * to the message list of this message.
+     *
+     * @param result the result status to use on this result
+     * @param throwable the throwable object from which to add the message and stack trace
+     */
+    public ApexAPIResult(final RESULT result, final Throwable throwable) {
+        this.result = result;
+        addThrowable(throwable);
+    }
+
+    /**
+     * This Constructor creates a result with the given result status, message, and
+     * {@link Throwable} object such as an exception. The message and stack trace from the
+     * {@link Throwable} object are added to the message list of this message.
+     *
+     * @param result the result status to use on this result
+     * @param message the message to return with the result
+     * @param throwable the throwable object from which to add the message and stack trace
+     */
+    public ApexAPIResult(final RESULT result, final String message, final Throwable throwable) {
+        this.result = result;
+        addMessage(message);
+        addThrowable(throwable);
+    }
+
+    /**
+     * This message is a utility message that checks if the result of an operation on the API was
+     * OK.
+     *
+     * @return true, if the result indicates the API operation succeeded
+     */
+    @XmlAttribute(required = true)
+    public boolean isOK() {
+        return result == RESULT.SUCCESS || result == RESULT.FINISHED;
+    }
+
+    /**
+     * This message is a utility message that checks if the result of an operation on the API was
+     * not OK.
+     *
+     * @return true, if the result indicates the API operation did not succeed
+     */
+    public boolean isNOK() {
+        return !isOK();
+    }
+
+    /**
+     * Gets the result status of an API operation.
+     *
+     * @return the result status
+     */
+    @XmlAttribute(required = true)
+    public RESULT getResult() {
+        return result;
+    }
+
+    /**
+     * Sets the result status of an API operation.
+     *
+     * @param result the result status
+     */
+    public void setResult(final RESULT result) {
+        this.result = result;
+    }
+
+    /**
+     * Gets the list of messages returned by an API operation.
+     *
+     * @return the list of messages returned by an API operation
+     */
+    @XmlElementWrapper(required = false, nillable = true)
+    @XmlElement(nillable = true, name = "message")
+    public List<String> getMessages() {
+        return messages;
+    }
+
+    /**
+     * Sets the list of messages to return as a result of an API operation.
+     *
+     * @param messages the list of messages to return as a result of an API operation
+     */
+    public void setMessages(final List<String> messages) {
+        this.messages = messages;
+    }
+
+    /**
+     * Gets all the messages returned by an API operation as a single string.
+     *
+     * @return the messages returned by an API operation as a single string
+     */
+    @XmlElement(required = true, name = "content")
+    public String getMessage() {
+        final StringBuilder builder = new StringBuilder();
+        for (final String message : messages) {
+            builder.append(message);
+            builder.append('\n');
+        }
+
+        return builder.toString();
+    }
+
+    /**
+     * Adds a message from an API operation to the bottom of the list of messages to be returned.
+     *
+     * @param message the message from an API operation to add to the bottom of the list of messages
+     *        to be returned
+     */
+    public void addMessage(final String message) {
+        if (message != null && message.trim().length() > 0) {
+            messages.add(message);
+        }
+    }
+
+    /**
+     * Adds the message and stack trace from a {@link Throwable} object such as an exception from an
+     * API operation to the bottom of the list of messages to be returned.
+     *
+     * @param throwable the {@link Throwable} object such as an exception from an API operation from
+     *        which the message and stack trace are to be extracted and placed at the bottom of the
+     *        list of messages to be returned
+     */
+    public void addThrowable(final Throwable throwable) {
+        final StringWriter throwableStringWriter = new StringWriter();
+        final PrintWriter throwablePrintWriter = new PrintWriter(throwableStringWriter);
+        throwable.printStackTrace(throwablePrintWriter);
+        messages.add(throwable.getMessage());
+        messages.add(throwableStringWriter.toString());
+    }
+
+    /**
+     * Gets a representation of the {@link ApexAPIResult} instance as a JSON string.
+     *
+     * @return the result instance JSON string
+     */
+    public String toJSON() {
+        final StringBuilder builder = new StringBuilder();
+        builder.append("{\n");
+
+        builder.append("\"result\": \"");
+        builder.append(result.toString());
+        builder.append("\",\n");
+
+        builder.append("\"messages\": [");
+        boolean first = true;
+        for (final String message : messages) {
+            if (first) {
+                builder.append("\n\"");
+                first = false;
+            } else {
+                builder.append(",\n\"");
+            }
+            builder.append(message.replaceAll("\"", "\\\\\""));
+            builder.append("\"");
+        }
+        builder.append("]\n");
+
+        builder.append("}\n");
+
+        return builder.toString();
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        final StringBuilder builder = new StringBuilder();
+        builder.append("result: ");
+        builder.append(result);
+        builder.append('\n');
+        builder.append(getMessage());
+        return builder.toString();
+    }
+}
diff --git a/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/ApexEditorAPI.java b/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/ApexEditorAPI.java
new file mode 100644
index 0000000..617cbc7
--- /dev/null
+++ b/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/ApexEditorAPI.java
@@ -0,0 +1,948 @@
+/*-
+ * ============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.model.modelapi;
+
+/**
+ * The Interface ApexEditorAPI is used to manipulate Apex models.
+ */
+public interface ApexEditorAPI {
+    /*
+     * Model API Methods
+     */
+
+    /**
+     * Create model.
+     *
+     * @param name name of the model
+     * @param version version of the model, set to null to use the default version
+     * @param uuid model UUID, set to null to generate a UUID
+     * @param description model description, set to null to generate a description
+     * @return result of the operation
+     */
+    ApexAPIResult createModel(final String name, final String version, final String uuid, final String description);
+
+    /**
+     * Update model.
+     *
+     * @param name name of the model
+     * @param version version of the model, set to null to update the latest version
+     * @param uuid key information UUID, set to null to not update
+     * @param description policy description, set to null to not update
+     * @return result of the operation
+     */
+    ApexAPIResult updateModel(final String name, final String version, final String uuid, final String description);
+
+    /**
+     * Get the key of an Apex model.
+     *
+     * @return the result of the operation
+     */
+    ApexAPIResult getModelKey();
+
+    /**
+     * List an Apex model.
+     *
+     * @return the result of the operation
+     */
+    ApexAPIResult listModel();
+
+    /**
+     * Delete an Apex model, clear all the concepts in the model.
+     *
+     * @return the result of the operation
+     */
+    ApexAPIResult deleteModel();
+
+    /*
+     * Key Information API Methods
+     */
+
+    /**
+     * Create key information.
+     *
+     * @param name name of the concept for the key information
+     * @param version version of the concept for the key information, set to null to use the default
+     *        version
+     * @param uuid key information UUID, set to null to generate a UUID
+     * @param description key information description, set to null to generate a description
+     * @return result of the operation
+     */
+    ApexAPIResult createKeyInformation(final String name, final String version, final String uuid,
+            final String description);
+
+    /**
+     * Update key information.
+     *
+     * @param name name of the concept for the key information
+     * @param version version of the concept for the key information, set to null to update the
+     *        latest version
+     * @param uuid key information UUID, set to null to not update
+     * @param description key information description, set to null to not update
+     * @return result of the operation
+     */
+    ApexAPIResult updateKeyInformation(final String name, final String version, final String uuid,
+            final String description);
+
+    /**
+     * List key information.
+     *
+     * @param name name of the concept for the key information, set to null to list all
+     * @param version starting version of the concept for the key information, set to null to list
+     *        all versions
+     * @return result of the operation
+     */
+    ApexAPIResult listKeyInformation(final String name, final String version);
+
+    /**
+     * Delete key information.
+     *
+     * @param name name of the concept for the key information
+     * @param version version of the concept for the key information, set to null to delete all
+     *        versions
+     * @return result of the operation
+     */
+    ApexAPIResult deleteKeyInformation(final String name, final String version);
+
+    /**
+     * Validate key information.
+     *
+     * @param name name of the concept for the key information
+     * @param version version of the concept for the key information, set to null to validate all
+     *        versions
+     * @return result of the operation
+     */
+    ApexAPIResult validateKeyInformation(final String name, final String version);
+
+    /*
+     * Context Schema API Methods
+     */
+
+    /**
+     * Create a context schema.
+     *
+     * @param name name of the context schema
+     * @param version version of the context schema, set to null to use the default version
+     * @param schemaFlavour a final String identifying the flavour of this context schema
+     * @param schemaDefinition a final String containing the definition of this context schema
+     * @param uuid context schema UUID, set to null to generate a UUID
+     * @param description context schema description, set to null to generate a description
+     * @return result of the operation
+     */
+    ApexAPIResult createContextSchema(final String name, final String version, final String schemaFlavour,
+            final String schemaDefinition, final String uuid, final String description);
+
+    /**
+     * Update a context schema.
+     *
+     * @param name name of the context schema
+     * @param version version of the context schema, set to null to update the latest version
+     * @param schemaFlavour a final String identifying the flavour of this context schema
+     * @param schemaDefinition a final String containing the definition of this context schema
+     * @param uuid context schema UUID, set to null to not update
+     * @param description context schema description, set to null to not update
+     * @return result of the operation
+     */
+    ApexAPIResult updateContextSchema(final String name, final String version, final String schemaFlavour,
+            final String schemaDefinition, final String uuid, final String description);
+
+    /**
+     * List context schemas.
+     *
+     * @param name name of the context schema, set to null to list all
+     * @param version starting version of the context schema, set to null to list all versions
+     * @return result of the operation
+     */
+    ApexAPIResult listContextSchemas(final String name, final String version);
+
+    /**
+     * Delete a context schema.
+     *
+     * @param name name of the context schema
+     * @param version version of the context schema, set to null to delete all versions
+     * @return result of the operation
+     */
+    ApexAPIResult deleteContextSchema(final String name, final String version);
+
+    /**
+     * Validate context schemas.
+     *
+     * @param name name of the context schema, set to null to list all
+     * @param version starting version of the context schema, set to null to list all versions
+     * @return result of the operation
+     */
+    ApexAPIResult validateContextSchemas(final String name, final String version);
+
+    /*
+     * Event API Methods
+     */
+
+    /**
+     * Create an event.
+     *
+     * @param name name of the event
+     * @param version version of the event, set to null to use the default version
+     * @param nameSpace of the event, set to null to use the default value
+     * @param source of the event, set to null to use the default value
+     * @param target of the event, set to null to use the default value
+     * @param uuid event UUID, set to null to generate a UUID
+     * @param description event description, set to null to generate a description
+     * @return result of the operation
+     */
+    ApexAPIResult createEvent(final String name, final String version, final String nameSpace, final String source,
+            final String target, final String uuid, final String description);
+
+    /**
+     * Update an event.
+     *
+     * @param name name of the event
+     * @param version version of the event, set to null to use the latest version
+     * @param nameSpace of the event, set to null to not update
+     * @param source of the event, set to null to not update
+     * @param target of the event, set to null to not update
+     * @param uuid event UUID, set to null to not update
+     * @param description event description, set to null to not update
+     * @return result of the operation
+     */
+    ApexAPIResult updateEvent(final String name, final String version, final String nameSpace, final String source,
+            final String target, final String uuid, final String description);
+
+    /**
+     * List events.
+     *
+     * @param name name of the event, set to null to list all
+     * @param version starting version of the event, set to null to list all versions
+     * @return result of the operation
+     */
+    ApexAPIResult listEvent(final String name, final String version);
+
+    /**
+     * Delete an event.
+     *
+     * @param name name of the event
+     * @param version version of the event, set to null to delete all versions
+     * @return result of the operation
+     */
+    ApexAPIResult deleteEvent(final String name, final String version);
+
+    /**
+     * Validate events.
+     *
+     * @param name name of the event, set to null to list all
+     * @param version starting version of the event, set to null to list all versions
+     * @return result of the operation
+     */
+    ApexAPIResult validateEvent(final String name, final String version);
+
+    /**
+     * Create an event parameter.
+     *
+     * @param name name of the event
+     * @param version version of the event, set to null to use the latest version
+     * @param parName of the parameter
+     * @param contextSchemaName name of the parameter context schema
+     * @param contextSchemaVersion version of the parameter context schema, set to null to use the
+     *        latest version
+     * @param optional true if the event parameter is optional, false otherwise
+     * @return result of the operation
+     */
+    ApexAPIResult createEventPar(final String name, final String version, final String parName,
+            final String contextSchemaName, final String contextSchemaVersion, boolean optional);
+
+    /**
+     * List event parameters.
+     *
+     * @param name name of the event
+     * @param version version of the event, set to null to list latest version
+     * @param parName name of the parameter, set to null to list all parameters of the event
+     * @return result of the operation
+     */
+    ApexAPIResult listEventPar(final String name, final String version, final String parName);
+
+    /**
+     * Delete an event parameter.
+     *
+     * @param name name of the event
+     * @param version version of the event, set to null to use the latest version
+     * @param parName of the parameter, set to null to delete all parameters
+     * @return result of the operation
+     */
+    ApexAPIResult deleteEventPar(final String name, final String version, final String parName);
+
+    /*
+     * Context Album API Methods
+     */
+
+    /**
+     * Create a context album.
+     *
+     * @param name name of the context album
+     * @param version version of the context album, set to null to use the default version
+     * @param scope of the context album
+     * @param writable "true" or "t" if the context album is writable, set to null or any other
+     *        value for a read-only album
+     * @param contextSchemaName name of the parameter context schema
+     * @param contextSchemaVersion version of the parameter context schema, set to null to use the
+     *        latest version
+     * @param uuid context album UUID, set to null to generate a UUID
+     * @param description context album description, set to null to generate a description
+     * @return result of the operation
+     */
+    // CHECKSTYLE:OFF: checkstyle:parameterNumber
+    ApexAPIResult createContextAlbum(final String name, final String version, final String scope, final String writable,
+            final String contextSchemaName, final String contextSchemaVersion, final String uuid,
+            final String description);
+    // CHECKSTYLE:ON: checkstyle:parameterNumber
+
+    /**
+     * Update a context album.
+     *
+     * @param name name of the context album
+     * @param version version of the context album, set to null to use the default version
+     * @param scope of the context album
+     * @param writable "true" or "t" if the context album is writable, set to null or any other
+     *        value for a read-only album
+     * @param contextSchemaName name of the parameter context schema
+     * @param contextSchemaVersion version of the parameter context schema, set to null to use the
+     *        latest version
+     * @param uuid context album UUID, set to null to generate a UUID
+     * @param description context album description, set to null to generate a description
+     * @return result of the operation
+     */
+    // CHECKSTYLE:OFF: checkstyle:parameterNumber
+    ApexAPIResult updateContextAlbum(final String name, final String version, final String scope, final String writable,
+            final String contextSchemaName, final String contextSchemaVersion, final String uuid,
+            final String description);
+    // CHECKSTYLE:ON: checkstyle:parameterNumber
+
+    /**
+     * List context albums.
+     *
+     * @param name name of the context album, set to null to list all
+     * @param version starting version of the context album, set to null to list all versions
+     * @return result of the operation
+     */
+    ApexAPIResult listContextAlbum(final String name, final String version);
+
+    /**
+     * Delete a context album.
+     *
+     * @param name name of the context album
+     * @param version version of the context album, set to null to delete versions
+     * @return result of the operation
+     */
+    ApexAPIResult deleteContextAlbum(final String name, final String version);
+
+    /**
+     * Validate context albums.
+     *
+     * @param name name of the context album, set to null to list all
+     * @param version starting version of the context album, set to null to list all versions
+     * @return result of the operation
+     */
+    ApexAPIResult validateContextAlbum(final String name, final String version);
+
+    /*
+     * Task API Methods
+     */
+
+    /**
+     * Create a task.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to use the default version
+     * @param uuid task UUID, set to null to generate a UUID
+     * @param description task description, set to null to generate a description
+     * @return result of the operation
+     */
+    ApexAPIResult createTask(final String name, final String version, final String uuid, final String description);
+
+    /**
+     * Update a task.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to use the latest version
+     * @param uuid task UUID, set to null to not update
+     * @param description task description, set to null to not update
+     * @return result of the operation
+     */
+    ApexAPIResult updateTask(final String name, final String version, final String uuid, final String description);
+
+    /**
+     * List tasks.
+     *
+     * @param name name of the task, set to null to list all
+     * @param version starting version of the task, set to null to list all versions
+     * @return result of the operation
+     */
+    ApexAPIResult listTask(final String name, final String version);
+
+    /**
+     * Delete a task.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to use the latest version
+     * @return result of the operation
+     */
+    ApexAPIResult deleteTask(final String name, final String version);
+
+    /**
+     * Validate tasks.
+     *
+     * @param name name of the task, set to null to list all
+     * @param version starting version of the task, set to null to list all versions
+     * @return result of the operation
+     */
+    ApexAPIResult validateTask(final String name, final String version);
+
+    /**
+     * Create logic for a task.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to use the latest version
+     * @param logicFlavour the task logic flavour for the task, set to null to use the default task
+     *        logic flavour
+     * @param logic the source code for the logic of the task
+     * @return result of the operation
+     */
+    ApexAPIResult createTaskLogic(final String name, final String version, final String logicFlavour,
+            final String logic);
+
+    /**
+     * Update logic for a task.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to use the latest version
+     * @param logicFlavour the task logic flavour for the task, set to null to not update
+     * @param logic the source code for the logic of the task, set to null to not update
+     * @return result of the operation
+     */
+    ApexAPIResult updateTaskLogic(final String name, final String version, final String logicFlavour,
+            final String logic);
+
+    /**
+     * List task logic.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to list the latest version
+     * @return result of the operation
+     */
+    ApexAPIResult listTaskLogic(final String name, final String version);
+
+    /**
+     * Delete logic for a task.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to use the latest version
+     * @return result of the operation
+     */
+    ApexAPIResult deleteTaskLogic(final String name, final String version);
+
+    /**
+     * Create a task input field.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to use the latest version
+     * @param fieldName of the input field
+     * @param contextSchemaName name of the input field context schema
+     * @param contextSchemaVersion version of the input field context schema, set to null to use the
+     *        latest version
+     * @param optional true if the task field is optional, false otherwise
+     * @return result of the operation
+     */
+    ApexAPIResult createTaskInputField(final String name, final String version, final String fieldName,
+            final String contextSchemaName, final String contextSchemaVersion, boolean optional);
+
+    /**
+     * List task input fields.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to use the latest version
+     * @param fieldName field name of the input field, set to null to list all input fields of the
+     *        task
+     * @return result of the operation
+     */
+    ApexAPIResult listTaskInputField(final String name, final String version, final String fieldName);
+
+    /**
+     * Delete a task input field.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to use the latest version
+     * @param fieldName of the input field, set to null to delete all input fields
+     * @return result of the operation
+     */
+    ApexAPIResult deleteTaskInputField(final String name, final String version, final String fieldName);
+
+    /**
+     * Create a task output field.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to use the latest version
+     * @param fieldName of the output field
+     * @param contextSchemaName name of the output field context schema
+     * @param contextSchemaVersion version of the output field context schema, set to null to use
+     *        the latest version
+     * @param optional true if the task field is optional, false otherwise
+     * @return result of the operation
+     */
+    ApexAPIResult createTaskOutputField(final String name, final String version, final String fieldName,
+            final String contextSchemaName, final String contextSchemaVersion, boolean optional);
+
+    /**
+     * List task output fields.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to use the latest version
+     * @param fieldName field name of the output field, set to null to list all output fields of the
+     *        task
+     * @return result of the operation
+     */
+    ApexAPIResult listTaskOutputField(final String name, final String version, final String fieldName);
+
+    /**
+     * Delete a task output field.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to use the latest version
+     * @param fieldName of the output field, set to null to delete all output fields
+     * @return result of the operation
+     */
+    ApexAPIResult deleteTaskOutputField(final String name, final String version, final String fieldName);
+
+    /**
+     * Create a task parameter.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to use the latest version
+     * @param parName of the parameter
+     * @param defaultValue of the parameter
+     * @return result of the operation
+     */
+    ApexAPIResult createTaskParameter(final String name, final String version, final String parName,
+            final String defaultValue);
+
+    /**
+     * List task parameters.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to use the latest version
+     * @param parName name of the parameter, set to null to list all parameters of the task
+     * @return result of the operation
+     */
+    ApexAPIResult listTaskParameter(final String name, final String version, final String parName);
+
+    /**
+     * Delete a task parameter.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to use the latest version
+     * @param parName of the parameter, set to null to delete all task parameters
+     * @return result of the operation
+     */
+    ApexAPIResult deleteTaskParameter(final String name, final String version, final String parName);
+
+    /**
+     * Create a task context album reference.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to use the latest version
+     * @param contextAlbumName name of the context album for the context album reference
+     * @param contextAlbumVersion version of the context album for the context album reference, set
+     *        to null to use the latest version
+     * @return result of the operation
+     */
+    ApexAPIResult createTaskContextRef(final String name, final String version, final String contextAlbumName,
+            final String contextAlbumVersion);
+
+    /**
+     * List task context album references.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to use the latest version
+     * @param contextAlbumName name of the context album for the context album reference, set to
+     *        null to list all task context album references
+     * @param contextAlbumVersion version of the context album for the context album reference, set
+     *        to null to use the latest version
+     * @return result of the operation
+     */
+    ApexAPIResult listTaskContextRef(final String name, final String version, final String contextAlbumName,
+            final String contextAlbumVersion);
+
+    /**
+     * Delete a task context album reference.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to use the latest version
+     * @param contextAlbumName name of the context album for the context album reference, set to
+     *        null to delete all task context album references
+     * @param contextAlbumVersion version of the context album for the context album reference, set
+     *        to null to use the latest version
+     * @return result of the operation
+     */
+    ApexAPIResult deleteTaskContextRef(final String name, final String version, final String contextAlbumName,
+            final String contextAlbumVersion);
+
+    /*
+     * Policy API Methods
+     */
+
+    /**
+     * Create a policy.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the default version
+     * @param template template used to create the policy, set to null to use the default template
+     * @param firstState the first state of the policy
+     * @param uuid policy UUID, set to null to generate a UUID
+     * @param description policy description, set to null to generate a description
+     * @return result of the operation
+     */
+    ApexAPIResult createPolicy(final String name, final String version, final String template, final String firstState,
+            final String uuid, final String description);
+
+    /**
+     * Update a policy.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param template template used to create the policy, set to null to not update
+     * @param firstState the first state of the policy
+     * @param uuid policy UUID, set to null to not update
+     * @param description policy description, set to null to not update
+     * @return result of the operation
+     */
+    ApexAPIResult updatePolicy(final String name, final String version, final String template, final String firstState,
+            final String uuid, final String description);
+
+    /**
+     * List policies.
+     *
+     * @param name name of the policy, set to null to list all
+     * @param version starting version of the policy, set to null to list all versions
+     * @return result of the operation
+     */
+    ApexAPIResult listPolicy(final String name, final String version);
+
+    /**
+     * Delete a policy.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @return result of the operation
+     */
+    ApexAPIResult deletePolicy(final String name, final String version);
+
+    /**
+     * Validate policies.
+     *
+     * @param name name of the policy, set to null to list all
+     * @param version starting version of the policy, set to null to list all versions
+     * @return result of the operation
+     */
+    ApexAPIResult validatePolicy(final String name, final String version);
+
+    /**
+     * Create a policy state.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state
+     * @param triggerName name of the trigger event for this state
+     * @param triggerVersion version of the trigger event for this state, set to null to use the
+     *        latest version
+     * @param defaultTaskName the default task name
+     * @param defaltTaskVersion the default task version, set to null to use the latest version
+     * @return result of the operation
+     */
+    ApexAPIResult createPolicyState(final String name, final String version, final String stateName,
+            final String triggerName, final String triggerVersion, final String defaultTaskName,
+            final String defaltTaskVersion);
+
+    /**
+     * Update a policy state.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state
+     * @param triggerName name of the trigger event for this state, set to null to not update
+     * @param triggerVersion version of the trigger event for this state, set to use latest version
+     *        of trigger event
+     * @param defaultTaskName the default task name, set to null to not update
+     * @param defaltTaskVersion the default task version, set to use latest version of default task
+     * @return result of the operation
+     */
+    ApexAPIResult updatePolicyState(final String name, final String version, final String stateName,
+            final String triggerName, final String triggerVersion, final String defaultTaskName,
+            final String defaltTaskVersion);
+
+    /**
+     * List policy states.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state, set to null to list all states of the policy
+     * @return result of the operation
+     */
+    ApexAPIResult listPolicyState(final String name, final String version, final String stateName);
+
+    /**
+     * Delete a policy state.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state, set to null to delete all states
+     * @return result of the operation
+     */
+    ApexAPIResult deletePolicyState(final String name, final String version, final String stateName);
+
+    /**
+     * Create task selection logic for a state.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state
+     * @param logicFlavour the task selection logic flavour for the state, set to null to use the
+     *        default task logic flavour
+     * @param logic the source code for the logic of the state
+     * @return result of the operation
+     */
+    ApexAPIResult createPolicyStateTaskSelectionLogic(final String name, final String version, final String stateName,
+            final String logicFlavour, final String logic);
+
+    /**
+     * Update task selection logic for a state.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state
+     * @param logicFlavour the task selection logic flavour for the state, set to null to not update
+     * @param logic the source code for the logic of the state, set to null to not update
+     * @return result of the operation
+     */
+    ApexAPIResult updatePolicyStateTaskSelectionLogic(final String name, final String version, final String stateName,
+            final String logicFlavour, final String logic);
+
+    /**
+     * List task selection logic for a state.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state
+     * @return result of the operation
+     */
+    ApexAPIResult listPolicyStateTaskSelectionLogic(final String name, final String version, final String stateName);
+
+    /**
+     * Delete task selection logic for a state.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state
+     * @return result of the operation
+     */
+    ApexAPIResult deletePolicyStateTaskSelectionLogic(final String name, final String version, final String stateName);
+
+    /**
+     * Create a policy state output.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state
+     * @param outputName of the state output
+     * @param eventName name of the output event for this state output
+     * @param eventVersion version of the output event for this state output, set to null to use the
+     *        latest version
+     * @param nextState for this state to transition to, set to null if this is the last state that
+     *        the policy transitions to on this branch
+     * @return result of the operation
+     */
+    ApexAPIResult createPolicyStateOutput(final String name, final String version, final String stateName,
+            final String outputName, final String eventName, final String eventVersion, final String nextState);
+
+    /**
+     * List policy state outputs.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state
+     * @param outputName of the state output, set to null to list all outputs of the state
+     * @return result of the operation
+     */
+    ApexAPIResult listPolicyStateOutput(final String name, final String version, final String stateName,
+            final String outputName);
+
+    /**
+     * Delete a policy state output.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state
+     * @param outputName of the state output, set to null to delete all state outputs
+     * @return result of the operation
+     */
+    ApexAPIResult deletePolicyStateOutput(final String name, final String version, final String stateName,
+            final String outputName);
+
+    /**
+     * Create policy finalizer logic for a state.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state
+     * @param finalizerLogicName name of the state finalizer logic
+     * @param logicFlavour the policy finalizer logic flavour for the state, set to null to use the
+     *        default task logic flavour
+     * @param logic the source code for the logic of the state
+     * @return result of the operation
+     */
+    ApexAPIResult createPolicyStateFinalizerLogic(final String name, final String version, final String stateName,
+            final String finalizerLogicName, final String logicFlavour, final String logic);
+
+    /**
+     * Update policy finalizer logic for a state.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state
+     * @param finalizerLogicName name of the state finalizer logic
+     * @param logicFlavour the policy finalizer logic flavour for the state, set to null to not
+     *        update
+     * @param logic the source code for the logic of the state, set to null to not update
+     * @return result of the operation
+     */
+    ApexAPIResult updatePolicyStateFinalizerLogic(final String name, final String version, final String stateName,
+            final String finalizerLogicName, final String logicFlavour, final String logic);
+
+    /**
+     * List policy finalizer logic for a state.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state
+     * @param finalizerLogicName name of the state finalizer logic
+     * @return result of the operation
+     */
+    ApexAPIResult listPolicyStateFinalizerLogic(final String name, final String version, final String stateName,
+            final String finalizerLogicName);
+
+    /**
+     * Delete policy finalizer logic for a state.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state
+     * @param finalizerLogicName name of the state finalizer logic
+     * @return result of the operation
+     */
+    ApexAPIResult deletePolicyStateFinalizerLogic(final String name, final String version, final String stateName,
+            final String finalizerLogicName);
+
+    /**
+     * Create a policy state task reference.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state
+     * @param taskLocalName the task local name
+     * @param taskName name of the task
+     * @param taskVersion version of the task, set to null to use the latest version
+     * @param outputType Type of output for the task, must be DIRECT for direct output to a state
+     *        output or LOGIC for output to state finalizer logic
+     * @param outputName the name of the state output or state state finalizer logic to handle the
+     *        task output
+     * @return result of the operation
+     */
+    // CHECKSTYLE:OFF: checkstyle:parameterNumber
+    ApexAPIResult createPolicyStateTaskRef(final String name, final String version, final String stateName,
+            final String taskLocalName, final String taskName, final String taskVersion, final String outputType,
+            final String outputName);
+    // CHECKSTYLE:ON: checkstyle:parameterNumber
+
+    /**
+     * List policy state task references.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state
+     * @param taskName name of the task, set to null to list all task references
+     * @param taskVersion version of the task, set to null to use the latest version
+     * @return result of the operation
+     */
+    ApexAPIResult listPolicyStateTaskRef(final String name, final String version, final String stateName,
+            final String taskName, final String taskVersion);
+
+    /**
+     * Delete a policy state task reference.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state
+     * @param taskName name of the task, set to null to delete all task references
+     * @param taskVersion version of the task, set to null to use the latest version
+     * @return result of the operation
+     */
+    ApexAPIResult deletePolicyStateTaskRef(final String name, final String version, final String stateName,
+            final String taskName, final String taskVersion);
+
+    /**
+     * Create a policy state context album reference.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state
+     * @param contextAlbumName name of the context album for the context album reference
+     * @param contextAlbumVersion version of the context album for the context album reference, set
+     *        to null to use the latest version
+     * @return result of the operation
+     */
+    ApexAPIResult createPolicyStateContextRef(final String name, final String version, final String stateName,
+            final String contextAlbumName, final String contextAlbumVersion);
+
+    /**
+     * List policy state context album references.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state
+     * @param contextAlbumName name of the context album for the context album reference, set to
+     *        null to list all task context album references
+     * @param contextAlbumVersion version of the context album for the context album reference, set
+     *        to null to use the latest version
+     * @return result of the operation
+     */
+    ApexAPIResult listPolicyStateContextRef(final String name, final String version, final String stateName,
+            final String contextAlbumName, final String contextAlbumVersion);
+
+    /**
+     * Delete a policy state context album reference.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the default version
+     * @param stateName of the state
+     * @param contextAlbumName name of the context album for the context album reference, set to
+     *        null to delete all task context album references
+     * @param contextAlbumVersion version of the context album for the context album reference, set
+     *        to null to use the latest version
+     * @return result of the operation
+     */
+    ApexAPIResult deletePolicyStateContextRef(final String name, final String version, final String stateName,
+            final String contextAlbumName, final String contextAlbumVersion);
+}
diff --git a/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/ApexModel.java b/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/ApexModel.java
new file mode 100644
index 0000000..c9190b8
--- /dev/null
+++ b/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/ApexModel.java
@@ -0,0 +1,192 @@
+/*
+ * ============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.model.modelapi;
+
+import org.onap.policy.apex.model.basicmodel.dao.DAOParameters;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+
+/**
+ * The Interface ApexModelAPI provides functional methods that allow Apex models to be managed.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public interface ApexModel extends ApexEditorAPI {
+    /**
+     * Make a deep copy of the Model.
+     *
+     * @return the result of the operation
+     */
+    ApexModel clone();
+
+    /**
+     * Load an Apex model from a string.
+     *
+     * @param modelString the string with the model
+     * @return the result of the operation
+     */
+    ApexAPIResult loadFromString(String modelString);
+
+    /**
+     * Load an Apex model from a file.
+     *
+     * @param fileName the file name of the file with the model
+     * @return the result of the operation
+     */
+    ApexAPIResult loadFromFile(String fileName);
+
+    /**
+     * Save an Apex model to a file.
+     *
+     * @param fileName the file name
+     * @param xmlFlag if true, save the file in XML format, otherwise save the file in the default JSON format
+     * @return the result of the operation
+     */
+    ApexAPIResult saveToFile(String fileName, boolean xmlFlag);
+
+    /**
+     * Load an Apex model from a database.
+     *
+     * @param modelName the name of the model to load
+     * @param modelVersion the version of the model to load, loads the policy model from the database with this name, if more than one exist, an exception is
+     *            thrown
+     * @param daoParameters the parameters to use to access the database over JDBC
+     * @return the result of the operation
+     */
+    ApexAPIResult loadFromDatabase(String modelName, String modelVersion, DAOParameters daoParameters);
+
+    /**
+     * Save an Apex model to a database.
+     *
+     * @param daoParameters the parameters to use to access the database over JDBC
+     * @return the result of the operation
+     */
+    ApexAPIResult saveToDatabase(DAOParameters daoParameters);
+
+    /**
+     * Read an APEX model from a location identified by a URL.
+     *
+     * @param urlString the url string
+     * @return the result of the operation
+     */
+    ApexAPIResult readFromURL(String urlString);
+
+    /**
+     * Write an APEX model to a location identified by a URL.
+     *
+     * @param urlString the URL to read the model from
+     * @param xmlFlag if true, save the file in XML format, otherwise save the file in the default JSON format
+     * @return the result of the operation
+     */
+    ApexAPIResult writeToURL(String urlString, boolean xmlFlag);
+
+    /**
+     * Analyse an Apex model that shows the concept usage references of a policy model.
+     *
+     * @return the result of the operation
+     */
+    ApexAPIResult analyse();
+
+    /**
+     * Validate an Apex model, checking all concepts and references in the model.
+     *
+     * @return the result of the operation
+     */
+    ApexAPIResult validate();
+
+    /**
+     * Compare to Apex models, returning the differences between the models.
+     *
+     * @param otherModelFileName the file name of the other model
+     * @param diffsOnly only returns differences between the model when set
+     * @param keysOnly only returns the keys that are different when set, when not set values are also returned
+     * @return the result of the operation
+     */
+    ApexAPIResult compare(String otherModelFileName, boolean diffsOnly, boolean keysOnly);
+
+    /**
+     * Compare two Apex models, returning the differences between the models.
+     *
+     * @param otherModelString the other model as a string
+     * @param diffsOnly only returns differences between the model when set
+     * @param keysOnly only returns the keys that are different when set, when not set values are also returned
+     * @return the result of the operation
+     */
+    ApexAPIResult compareWithString(String otherModelString, boolean diffsOnly, boolean keysOnly);
+
+    /**
+     * Split out a sub model from an Apex model that contains a given subset of the policies in the original model.
+     *
+     * @param targetModelName the file name of the target model in which to store the model split out from the original model
+     * @param splitOutPolicies the policies form the original model to include in the split out model, specified as a comma delimited list of policy names
+     * @return the result of the operation
+     */
+    ApexAPIResult split(String targetModelName, String splitOutPolicies);
+
+    /**
+     * Split out a sub model from an Apex model that contains a given subset of the policies in the original model, return the split model in the result as a
+     * string.
+     *
+     * @param splitOutPolicies the policies form the original model to include in the split out model, specified as a comma delimited list of policy names
+     * @return the result of the operation
+     */
+    ApexAPIResult split(String splitOutPolicies);
+
+    /**
+     * Merge two Apex models together.
+     *
+     * @param mergeInModelName the file name of the model to merge into the current model
+     * @param keepOriginal if this flag is set to true, if a concept exists in both models, the original model copy of that concept is kept, if the flag is set
+     *            to false, then the copy of the concept from the mergeInModel overwrites the concept in the original model
+     * @return the result of the operation
+     */
+    ApexAPIResult merge(String mergeInModelName, boolean keepOriginal);
+
+    /**
+     * Merge two Apex models together.
+     *
+     * @param otherModelString the model to merge as a string
+     * @param keepOriginal if this flag is set to true, if a concept exists in both models, the original model copy of that concept is kept, if the flag is set
+     *            to false, then the copy of the concept from the mergeInModel overwrites the concept in the original model
+     * @return the result of the operation
+     */
+    ApexAPIResult mergeWithString(String otherModelString, boolean keepOriginal);
+
+    /**
+     * Get the raw policy model being used by this model.
+     *
+     * @return the policy model
+     */
+    AxPolicyModel getPolicyModel();
+
+    /**
+     * Set the raw policy model being used by this model.
+     *
+     * @param policyModel the policy model
+     */
+    void setPolicyModel(AxPolicyModel policyModel);
+    
+    /**
+     * Builds the raw policy model being used by this model.
+     *
+     * @return the policy model
+     */
+    AxPolicyModel build();
+}
diff --git a/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/ApexModelFactory.java b/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/ApexModelFactory.java
new file mode 100644
index 0000000..ad0f0b4
--- /dev/null
+++ b/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/ApexModelFactory.java
@@ -0,0 +1,78 @@
+/*-
+ * ============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.model.modelapi;
+
+import java.util.Properties;
+
+import org.onap.policy.apex.model.modelapi.impl.ApexModelImpl;
+
+/**
+ * A factory for creating ApexModel objects using the Apex Model implementation.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ApexModelFactory {
+
+    /**
+     * Creates a new ApexModel object from its implementation.
+     *
+     * @param apexProperties default values and other configuration information for the apex model
+     * @param jsonMode set to true to return JSON strings in list and delete operations, otherwise
+     *        set to false
+     * @return the apex model
+     */
+    public ApexModel createApexModel(final Properties apexProperties, final boolean jsonMode) {
+        return new ApexModelImpl(setDefaultPropertyValues(apexProperties), jsonMode);
+    }
+
+    /**
+     * Sets default property values for Apex properties that must be set for the Apex model
+     * implementation if those properties are not already set.
+     *
+     * @param apexPropertiesIn the default property values
+     * @return the properties
+     */
+    private Properties setDefaultPropertyValues(final Properties apexPropertiesIn) {
+        Properties apexProperties = apexPropertiesIn;
+
+        if (apexProperties == null) {
+            apexProperties = new Properties();
+        }
+
+        if (apexProperties.getProperty("DEFAULT_CONCEPT_VERSION") == null) {
+            apexProperties.setProperty("DEFAULT_CONCEPT_VERSION", "0.0.1");
+        }
+        if (apexProperties.getProperty("DEFAULT_EVENT_NAMESPACE") == null) {
+            apexProperties.setProperty("DEFAULT_EVENT_NAMESPACE", "org.onap.policy.apex");
+        }
+        if (apexProperties.getProperty("DEFAULT_EVENT_SOURCE") == null) {
+            apexProperties.setProperty("DEFAULT_EVENT_SOURCE", "source");
+        }
+        if (apexProperties.getProperty("DEFAULT_EVENT_TARGET") == null) {
+            apexProperties.setProperty("DEFAULT_EVENT_TARGET", "target");
+        }
+        if (apexProperties.getProperty("DEFAULT_POLICY_TEMPLATE") == null) {
+            apexProperties.setProperty("DEFAULT_POLICY_TEMPLATE", "FREEFORM");
+        }
+
+        return apexProperties;
+    }
+}
diff --git a/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/impl/ApexModelImpl.java b/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/impl/ApexModelImpl.java
new file mode 100644
index 0000000..5303e95
--- /dev/null
+++ b/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/impl/ApexModelImpl.java
@@ -0,0 +1,1239 @@
+/*-
+ * ============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.model.modelapi.impl;
+
+import java.util.Properties;
+
+import org.onap.policy.apex.model.basicmodel.dao.DAOParameters;
+import org.onap.policy.apex.model.modelapi.ApexAPIResult;
+import org.onap.policy.apex.model.modelapi.ApexModel;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+
+/**
+ * This class is an implementation of a facade on an Apex model for editors of Apex models.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public final class ApexModelImpl implements ApexModel {
+    private static final int HASH_CODE_PRIME_0 = 31;
+    private static final int HASH_CODE_PRIME_1 = 1231;
+    private static final int HASH_CODE_PRIME_2 = 1237;
+
+    // The policy model being acted upon
+    private AxPolicyModel policyModel = new AxPolicyModel();
+
+    // The file name for the loaded file
+    private String fileName = null;
+
+    // Facade classes for working towards the real Apex model
+    // @formatter:off
+    private ModelFacade modelFacade;
+    private KeyInformationFacade keyInformationFacade;
+    private ContextSchemaFacade contextSchemaFacade;
+    private EventFacade eventFacade;
+    private ContextAlbumFacade contextAlbumFacade;
+    private TaskFacade taskFacade;
+    private PolicyFacade policyFacade;
+    private ModelHandlerFacade modelHandlerFacade;
+    // @formatter:on
+
+    private Properties apexProperties;
+    private boolean jsonMode;
+
+    /**
+     * Create an implementation of the Apex editor and model APIs.
+     *
+     * @param apexProperties The properties to use for the model
+     * @param jsonMode set to true to return JSON strings in list and delete operations, otherwise
+     *        set to false
+     */
+    public ApexModelImpl(final Properties apexProperties, final boolean jsonMode) {
+        this.apexProperties = apexProperties;
+        this.jsonMode = jsonMode;
+
+        // @formatter:off
+        this.modelFacade          = new ModelFacade(this, apexProperties, jsonMode);
+        this.keyInformationFacade = new KeyInformationFacade(this, apexProperties, jsonMode);
+        this.contextSchemaFacade  = new ContextSchemaFacade(this, apexProperties, jsonMode);
+        this.eventFacade          = new EventFacade(this, apexProperties, jsonMode);
+        this.contextAlbumFacade   = new ContextAlbumFacade(this, apexProperties, jsonMode);
+        this.taskFacade           = new TaskFacade(this, apexProperties, jsonMode);
+        this.policyFacade         = new PolicyFacade(this, apexProperties, jsonMode);
+        this.modelHandlerFacade   = new ModelHandlerFacade(this, apexProperties, jsonMode);
+        // @formatter:on
+    }
+
+    /**
+     * Constructor, prevents this class being sub-classed.
+     */
+    private ApexModelImpl() {}
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.core.modelapi.ApexModel#clone()
+     */
+    @Override
+    public ApexModel clone() {
+        ApexModelImpl ret = new ApexModelImpl();
+        // @formatter:off
+        ret.policyModel          = new AxPolicyModel(policyModel);
+        ret.fileName             = this.fileName;
+        ret.apexProperties       = this.apexProperties;
+        ret.jsonMode             = this.jsonMode;
+        ret.modelFacade          = new ModelFacade(ret, this.apexProperties, this.jsonMode);
+        ret.keyInformationFacade = new KeyInformationFacade(ret, this.apexProperties, this.jsonMode);
+        ret.contextSchemaFacade  = new ContextSchemaFacade(ret, this.apexProperties, this.jsonMode);
+        ret.eventFacade          = new EventFacade(ret, this.apexProperties, this.jsonMode);
+        ret.contextAlbumFacade   = new ContextAlbumFacade(ret, this.apexProperties, this.jsonMode);
+        ret.taskFacade           = new TaskFacade(ret, this.apexProperties, this.jsonMode);
+        ret.policyFacade         = new PolicyFacade(ret, this.apexProperties, this.jsonMode);
+        ret.modelHandlerFacade   = new ModelHandlerFacade(ret, this.apexProperties, this.jsonMode);
+        // @formatter:on
+
+        return ret;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.core.modelapi.ApexModel#createModel(java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult createModel(final String name, final String version, final String uuid,
+            final String description) {
+        return modelFacade.createModel(name, version, uuid, description);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.core.modelapi.ApexModel#updateModel(java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult updateModel(final String name, final String version, final String uuid,
+            final String description) {
+        return modelFacade.updateModel(name, version, uuid, description);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.core.modelapi.ApexEditorAPI#getModelKey()
+     */
+    @Override
+    public ApexAPIResult getModelKey() {
+        return modelFacade.getModelKey();
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#listModel()
+     */
+    @Override
+    public ApexAPIResult listModel() {
+        return modelFacade.listModel();
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#deleteModel()
+     */
+    @Override
+    public ApexAPIResult deleteModel() {
+        return modelFacade.deleteModel();
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#createKeyInformation(java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult createKeyInformation(final String name, final String version, final String uuid,
+            final String description) {
+        return keyInformationFacade.createKeyInformation(name, version, uuid, description);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#updateKeyInformation(java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult updateKeyInformation(final String name, final String version, final String uuid,
+            final String description) {
+        return keyInformationFacade.updateKeyInformation(name, version, uuid, description);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#listKeyInformation(java.lang.String,
+     * java.lang.String)
+     */
+    @Override
+    public ApexAPIResult listKeyInformation(final String name, final String version) {
+        return keyInformationFacade.listKeyInformation(name, version);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#deleteKeyInformation(java.lang.String,
+     * java.lang.String)
+     */
+    @Override
+    public ApexAPIResult deleteKeyInformation(final String name, final String version) {
+        return keyInformationFacade.deleteKeyInformation(name, version);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#validateKeyInformation(java.lang.String,
+     * java.lang.String)
+     */
+    @Override
+    public ApexAPIResult validateKeyInformation(final String name, final String version) {
+        return keyInformationFacade.validateKeyInformation(name, version);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#createContextSchema(java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult createContextSchema(final String name, final String version, final String schemaFlavour,
+            final String schemaDefinition, final String uuid, final String description) {
+        return contextSchemaFacade.createContextSchema(name, version, schemaFlavour, schemaDefinition, uuid,
+                description);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#updateContextSchema(java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult updateContextSchema(final String name, final String version, final String schemaFlavour,
+            final String schemaDefinition, final String uuid, final String description) {
+        return contextSchemaFacade.updateContextSchema(name, version, schemaFlavour, schemaDefinition, uuid,
+                description);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#listContextSchemas(java.lang.String,
+     * java.lang.String)
+     */
+    @Override
+    public ApexAPIResult listContextSchemas(final String name, final String version) {
+        return contextSchemaFacade.listContextSchemas(name, version);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#deleteContextSchema(java.lang.String,
+     * java.lang.String)
+     */
+    @Override
+    public ApexAPIResult deleteContextSchema(final String name, final String version) {
+        return contextSchemaFacade.deleteContextSchema(name, version);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#validateContextSchemas(java.lang.String,
+     * java.lang.String)
+     */
+    @Override
+    public ApexAPIResult validateContextSchemas(final String name, final String version) {
+        return contextSchemaFacade.validateContextSchemas(name, version);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#createEvent(java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String,
+     * java.lang.String)
+     */
+    @Override
+    public ApexAPIResult createEvent(final String name, final String version, final String nameSpace,
+            final String source, final String target, final String uuid, final String description) {
+        return eventFacade.createEvent(name, version, nameSpace, source, target, uuid, description);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#updateEvent(java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String,
+     * java.lang.String)
+     */
+    @Override
+    public ApexAPIResult updateEvent(final String name, final String version, final String nameSpace,
+            final String source, final String target, final String uuid, final String description) {
+        return eventFacade.updateEvent(name, version, nameSpace, source, target, uuid, description);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#listEvent(java.lang.String,
+     * java.lang.String)
+     */
+    @Override
+    public ApexAPIResult listEvent(final String name, final String version) {
+        return eventFacade.listEvent(name, version);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#deleteEvent(java.lang.String,
+     * java.lang.String)
+     */
+    @Override
+    public ApexAPIResult deleteEvent(final String name, final String version) {
+        return eventFacade.deleteEvent(name, version);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#validateEvent(java.lang.String,
+     * java.lang.String)
+     */
+    @Override
+    public ApexAPIResult validateEvent(final String name, final String version) {
+        return eventFacade.validateEvent(name, version);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.model.modelapi.ApexEditorAPI#createEventPar(java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String, java.lang.String, boolean)
+     */
+    @Override
+    public ApexAPIResult createEventPar(final String name, final String version, final String parName,
+            final String contextSchemaName, final String contextSchemaVersion, final boolean optional) {
+        return eventFacade.createEventPar(name, version, parName, contextSchemaName, contextSchemaVersion, optional);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#listEventPar(java.lang.String,
+     * java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult listEventPar(final String name, final String version, final String parName) {
+        return eventFacade.listEventPar(name, version, parName);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#deleteEventPar(java.lang.String,
+     * java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult deleteEventPar(final String name, final String version, final String parName) {
+        return eventFacade.deleteEventPar(name, version, parName);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.model.modelapi.ApexEditorAPI#createContextAlbum(java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String,
+     * java.lang.String, java.lang.String)
+     */
+    @Override
+    // CHECKSTYLE:OFF: checkstyle:parameterNumber
+    public ApexAPIResult createContextAlbum(final String name, final String version, final String scope,
+            final String writable, final String contextSchemaName, final String contextSchemaVersion, final String uuid,
+            final String description) {
+        return contextAlbumFacade.createContextAlbum(name, version, scope, writable, contextSchemaName,
+                contextSchemaVersion, uuid, description);
+    }
+    // CHECKSTYLE:ON: checkstyle:parameterNumber
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.model.modelapi.ApexEditorAPI#updateContextAlbum(java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String,
+     * java.lang.String, java.lang.String)
+     */
+    // CHECKSTYLE:OFF: checkstyle:parameterNumber
+    @Override
+    public ApexAPIResult updateContextAlbum(final String name, final String version, final String scope,
+            final String writable, final String contextSchemaName, final String contextSchemaVersion, final String uuid,
+            final String description) {
+        return contextAlbumFacade.updateContextAlbum(name, version, scope, writable, contextSchemaName,
+                contextSchemaVersion, uuid, description);
+    }
+    // CHECKSTYLE:ON: checkstyle:parameterNumber
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#listContextAlbum(java.lang.String,
+     * java.lang.String)
+     */
+    @Override
+    public ApexAPIResult listContextAlbum(final String name, final String version) {
+        return contextAlbumFacade.listContextAlbum(name, version);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#deleteContextAlbum(java.lang.String,
+     * java.lang.String)
+     */
+    @Override
+    public ApexAPIResult deleteContextAlbum(final String name, final String version) {
+        return contextAlbumFacade.deleteContextAlbum(name, version);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#validateContextAlbum(java.lang.String,
+     * java.lang.String)
+     */
+    @Override
+    public ApexAPIResult validateContextAlbum(final String name, final String version) {
+        return contextAlbumFacade.validateContextAlbum(name, version);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#createTask(java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult createTask(final String name, final String version, final String uuid,
+            final String description) {
+        return taskFacade.createTask(name, version, uuid, description);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#updateTask(java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult updateTask(final String name, final String version, final String uuid,
+            final String description) {
+        return taskFacade.updateTask(name, version, uuid, description);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#listTask(java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult listTask(final String name, final String version) {
+        return taskFacade.listTask(name, version);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#deleteTask(java.lang.String,
+     * java.lang.String)
+     */
+    @Override
+    public ApexAPIResult deleteTask(final String name, final String version) {
+        return taskFacade.deleteTask(name, version);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#validateTask(java.lang.String,
+     * java.lang.String)
+     */
+    @Override
+    public ApexAPIResult validateTask(final String name, final String version) {
+        return taskFacade.validateTask(name, version);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#createTaskLogic(java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult createTaskLogic(final String name, final String version, final String logicFlavour,
+            final String logic) {
+        return taskFacade.createTaskLogic(name, version, logicFlavour, logic);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#updateTaskLogic(java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult updateTaskLogic(final String name, final String version, final String logicFlavour,
+            final String logic) {
+        return taskFacade.updateTaskLogic(name, version, logicFlavour, logic);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#listTaskLogic(java.lang.String,
+     * java.lang.String)
+     */
+    @Override
+    public ApexAPIResult listTaskLogic(final String name, final String version) {
+        return taskFacade.listTaskLogic(name, version);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#deleteTaskLogic(java.lang.String,
+     * java.lang.String)
+     */
+    @Override
+    public ApexAPIResult deleteTaskLogic(final String name, final String version) {
+        return taskFacade.deleteTaskLogic(name, version);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#createTaskInputField(java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.boolean)
+     */
+    @Override
+    public ApexAPIResult createTaskInputField(final String name, final String version, final String fieldName,
+            final String dataTypeName, final String dataTypeVersion, final boolean optional) {
+        return taskFacade.createTaskInputField(name, version, fieldName, dataTypeName, dataTypeVersion, optional);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#listTaskInputField(java.lang.String,
+     * java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult listTaskInputField(final String name, final String version, final String fieldName) {
+        return taskFacade.listTaskInputField(name, version, fieldName);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#deleteTaskInputField(java.lang.String,
+     * java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult deleteTaskInputField(final String name, final String version, final String fieldName) {
+        return taskFacade.deleteTaskInputField(name, version, fieldName);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#createTaskOutputField(java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.boolean)
+     */
+    @Override
+    public ApexAPIResult createTaskOutputField(final String name, final String version, final String fieldName,
+            final String dataTypeName, final String dataTypeVersion, final boolean optional) {
+        return taskFacade.createTaskOutputField(name, version, fieldName, dataTypeName, dataTypeVersion, optional);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#listTaskOutputField(java.lang.String,
+     * java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult listTaskOutputField(final String name, final String version, final String fieldName) {
+        return taskFacade.listTaskOutputField(name, version, fieldName);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#deleteTaskOutputField(java.lang.String,
+     * java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult deleteTaskOutputField(final String name, final String version, final String fieldName) {
+        return taskFacade.deleteTaskOutputField(name, version, fieldName);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#createTaskParameter(java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult createTaskParameter(final String name, final String version, final String parName,
+            final String defaultValue) {
+        return taskFacade.createTaskParameter(name, version, parName, defaultValue);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#listTaskParameter(java.lang.String,
+     * java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult listTaskParameter(final String name, final String version, final String parName) {
+        return taskFacade.listTaskParameter(name, version, parName);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#deleteTaskParameter(java.lang.String,
+     * java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult deleteTaskParameter(final String name, final String version, final String parName) {
+        return taskFacade.deleteTaskParameter(name, version, parName);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#createTaskContextRef(java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult createTaskContextRef(final String name, final String version, final String contextAlbumName,
+            final String contextAlbumVersion) {
+        return taskFacade.createTaskContextRef(name, version, contextAlbumName, contextAlbumVersion);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#listTaskContextRef(java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult listTaskContextRef(final String name, final String version, final String contextAlbumName,
+            final String contextAlbumVersion) {
+        return taskFacade.listTaskContextRef(name, version, contextAlbumName, contextAlbumVersion);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#deleteTaskContextRef(java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult deleteTaskContextRef(final String name, final String version, final String contextAlbumName,
+            final String contextAlbumVersion) {
+        return taskFacade.deleteTaskContextRef(name, version, contextAlbumName, contextAlbumVersion);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#createPolicy(java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult createPolicy(final String name, final String version, final String template,
+            final String firstState, final String uuid, final String description) {
+        return policyFacade.createPolicy(name, version, template, firstState, uuid, description);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#updatePolicy(java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult updatePolicy(final String name, final String version, final String template,
+            final String firstState, final String uuid, final String description) {
+        return policyFacade.updatePolicy(name, version, template, firstState, uuid, description);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#listPolicy(java.lang.String,
+     * java.lang.String)
+     */
+    @Override
+    public ApexAPIResult listPolicy(final String name, final String version) {
+        return policyFacade.listPolicy(name, version);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#deletePolicy(java.lang.String,
+     * java.lang.String)
+     */
+    @Override
+    public ApexAPIResult deletePolicy(final String name, final String version) {
+        return policyFacade.deletePolicy(name, version);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#validatePolicy(java.lang.String,
+     * java.lang.String)
+     */
+    @Override
+    public ApexAPIResult validatePolicy(final String name, final String version) {
+        return policyFacade.validatePolicy(name, version);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#createPolicyState(java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String,
+     * java.lang.String)
+     */
+    @Override
+    public ApexAPIResult createPolicyState(final String name, final String version, final String stateName,
+            final String triggerName, final String triggerVersion, final String defaultTaskName,
+            final String defaltTaskVersion) {
+        return policyFacade.createPolicyState(name, version, stateName, triggerName, triggerVersion, defaultTaskName,
+                defaltTaskVersion);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#updatePolicyState(java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String,
+     * java.lang.String)
+     */
+    @Override
+    public ApexAPIResult updatePolicyState(final String name, final String version, final String stateName,
+            final String triggerName, final String triggerVersion, final String defaultTaskName,
+            final String defaltTaskVersion) {
+        return policyFacade.updatePolicyState(name, version, stateName, triggerName, triggerVersion, defaultTaskName,
+                defaltTaskVersion);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#listPolicyState(java.lang.String,
+     * java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult listPolicyState(final String name, final String version, final String stateName) {
+        return policyFacade.listPolicyState(name, version, stateName);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#deletePolicyState(java.lang.String,
+     * java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult deletePolicyState(final String name, final String version, final String stateName) {
+        return policyFacade.deletePolicyState(name, version, stateName);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see
+     * org.onap.policy.apex.auth.api.ApexEditorAPI#createPolicyStateTaskSelectionLogic(java.lang.
+     * String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult createPolicyStateTaskSelectionLogic(final String name, final String version,
+            final String stateName, final String logicFlavour, final String logic) {
+        return policyFacade.createPolicyStateTaskSelectionLogic(name, version, stateName, logicFlavour, logic);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see
+     * org.onap.policy.apex.auth.api.ApexEditorAPI#updatePolicyStateTaskSelectionLogic(java.lang.
+     * String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult updatePolicyStateTaskSelectionLogic(final String name, final String version,
+            final String stateName, final String logicFlavour, final String logic) {
+        return policyFacade.updatePolicyStateTaskSelectionLogic(name, version, stateName, logicFlavour, logic);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#listPolicyStateTaskSelectionLogic(java.lang.
+     * String, java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult listPolicyStateTaskSelectionLogic(final String name, final String version,
+            final String stateName) {
+        return policyFacade.listPolicyStateTaskSelectionLogic(name, version, stateName);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see
+     * org.onap.policy.apex.auth.api.ApexEditorAPI#deletePolicyStateTaskSelectionLogic(java.lang.
+     * String, java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult deletePolicyStateTaskSelectionLogic(final String name, final String version,
+            final String stateName) {
+        return policyFacade.deletePolicyStateTaskSelectionLogic(name, version, stateName);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#createPolicyStateOutput(java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String,
+     * java.lang.String)
+     */
+    @Override
+    public ApexAPIResult createPolicyStateOutput(final String name, final String version, final String stateName,
+            final String outputName, final String eventName, final String eventVersion, final String nextState) {
+        return policyFacade.createPolicyStateOutput(name, version, stateName, outputName, eventName, eventVersion,
+                nextState);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#listPolicyStateOutput(java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult listPolicyStateOutput(final String name, final String version, final String stateName,
+            final String outputName) {
+        return policyFacade.listPolicyStateOutput(name, version, stateName, outputName);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#deletePolicyStateOutput(java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult deletePolicyStateOutput(final String name, final String version, final String stateName,
+            final String outputName) {
+        return policyFacade.deletePolicyStateOutput(name, version, stateName, outputName);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see
+     * org.onap.policy.apex.core.modelapi.ApexEditorAPI#createPolicyStateFinalizerLogic(java.lang.
+     * String, java.lang.String, java.lang.String, java.lang.String, java.lang.String,
+     * java.lang.String)
+     */
+    @Override
+    public ApexAPIResult createPolicyStateFinalizerLogic(final String name, final String version,
+            final String stateName, final String finalizerLogicName, final String logicFlavour, final String logic) {
+        return policyFacade.createPolicyStateFinalizerLogic(name, version, stateName, finalizerLogicName, logicFlavour,
+                logic);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see
+     * org.onap.policy.apex.core.modelapi.ApexEditorAPI#updatePolicyStateFinalizerLogic(java.lang.
+     * String, java.lang.String, java.lang.String, java.lang.String, java.lang.String,
+     * java.lang.String)
+     */
+    @Override
+    public ApexAPIResult updatePolicyStateFinalizerLogic(final String name, final String version,
+            final String stateName, final String finalizerLogicName, final String logicFlavour, final String logic) {
+        return policyFacade.updatePolicyStateFinalizerLogic(name, version, stateName, finalizerLogicName, logicFlavour,
+                logic);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see
+     * org.onap.policy.apex.core.modelapi.ApexEditorAPI#listPolicyStateFinalizerLogic(java.lang.
+     * String, java.lang.String, java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult listPolicyStateFinalizerLogic(final String name, final String version, final String stateName,
+            final String finalizerLogicName) {
+        return policyFacade.listPolicyStateFinalizerLogic(name, version, stateName, finalizerLogicName);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see
+     * org.onap.policy.apex.core.modelapi.ApexEditorAPI#deletePolicyStateFinalizerLogic(java.lang.
+     * String, java.lang.String, java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult deletePolicyStateFinalizerLogic(final String name, final String version,
+            final String stateName, final String finalizerLogicName) {
+        return policyFacade.deletePolicyStateFinalizerLogic(name, version, stateName, finalizerLogicName);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see
+     * org.onap.policy.apex.core.modelapi.ApexEditorAPI#createPolicyStateTaskRef(java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String,
+     * java.lang.String, java.lang.String)
+     */
+    @Override
+    // CHECKSTYLE:OFF: checkstyle:parameterNumber
+    public ApexAPIResult createPolicyStateTaskRef(final String name, final String version, final String stateName,
+            final String taskLocalName, final String taskName, final String taskVersion, final String outputType,
+            final String outputName) {
+        return policyFacade.createPolicyStateTaskRef(name, version, stateName, taskLocalName, taskName, taskVersion,
+                outputType, outputName);
+    }
+    // CHECKSTYLE:ON: checkstyle:parameterNumber
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#listPolicyStateTaskRef(java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult listPolicyStateTaskRef(final String name, final String version, final String stateName,
+            final String taskName, final String taskVersion) {
+        return policyFacade.listPolicyStateTaskRef(name, version, stateName, taskName, taskVersion);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#deletePolicyStateTaskRef(java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult deletePolicyStateTaskRef(final String name, final String version, final String stateName,
+            final String taskName, final String taskVersion) {
+        return policyFacade.deletePolicyStateTaskRef(name, version, stateName, taskName, taskVersion);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see
+     * org.onap.policy.apex.auth.api.ApexEditorAPI#createPolicyStateContextRef(java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult createPolicyStateContextRef(final String name, final String version, final String stateName,
+            final String contextAlbumName, final String contextAlbumVersion) {
+        return policyFacade.createPolicyStateContextRef(name, version, stateName, contextAlbumName,
+                contextAlbumVersion);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexEditorAPI#listPolicyStateContextRef(java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult listPolicyStateContextRef(final String name, final String version, final String stateName,
+            final String contextAlbumName, final String contextAlbumVersion) {
+        return policyFacade.listPolicyStateContextRef(name, version, stateName, contextAlbumName, contextAlbumVersion);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see
+     * org.onap.policy.apex.auth.api.ApexEditorAPI#deletePolicyStateContextRef(java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult deletePolicyStateContextRef(final String name, final String version, final String stateName,
+            final String contextAlbumName, final String contextAlbumVersion) {
+        return policyFacade.deletePolicyStateContextRef(name, version, stateName, contextAlbumName,
+                contextAlbumVersion);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.core.modelapi.ApexModel#loadFromString(java.lang.String)
+     */
+    @Override
+    public ApexAPIResult loadFromString(final String modelString) {
+        return modelHandlerFacade.loadFromString(modelString);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexModel#loadFromFile(java.lang.String)
+     */
+    @Override
+    // CHECKSTYLE:OFF: checkstyle:HiddenField
+    public ApexAPIResult loadFromFile(final String fileName) {
+        this.fileName = fileName;
+        return modelHandlerFacade.loadFromFile(fileName);
+    }
+    // CHECKSTYLE:ON: checkstyle:HiddenField
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexModel#saveToFile(java.lang.String, boolean)
+     */
+    @Override
+    public ApexAPIResult saveToFile(final String saveFileName, final boolean xmlFlag) {
+        if (saveFileName == null) {
+            return modelHandlerFacade.saveToFile(fileName, xmlFlag);
+        } else {
+            return modelHandlerFacade.saveToFile(saveFileName, xmlFlag);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.model.modelapi.ApexModel#loadFromDatabase(java.lang.String,
+     * java.lang.String, org.onap.policy.apex.model.basicmodel.dao.DAOParameters)
+     */
+    @Override
+    public ApexAPIResult loadFromDatabase(final String modelName, final String modelVersion,
+            final DAOParameters daoParameters) {
+        return modelHandlerFacade.loadFromDatabase(modelName, modelVersion, daoParameters);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.model.modelapi.ApexModel#saveToDatabase(org.onap.policy.apex.model.
+     * basicmodel. dao.DAOParameters)
+     */
+    @Override
+    public ApexAPIResult saveToDatabase(final DAOParameters daoParameters) {
+        return modelHandlerFacade.saveToDatabase(daoParameters);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexModel#readFromURL(java.lang.String)
+     */
+    @Override
+    public ApexAPIResult readFromURL(final String urlString) {
+        return modelHandlerFacade.readFromURL(urlString);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexModel#writeToURL(java.lang.String, boolean)
+     */
+    @Override
+    public ApexAPIResult writeToURL(final String urlString, final boolean xmlFlag) {
+        return modelHandlerFacade.writeToURL(urlString, xmlFlag);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexModel#analyse()
+     */
+    @Override
+    public ApexAPIResult analyse() {
+        return modelHandlerFacade.analyse();
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexModel#validate()
+     */
+    @Override
+    public ApexAPIResult validate() {
+        return modelHandlerFacade.validate();
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexModel#compare(java.lang.String, boolean, boolean)
+     */
+    @Override
+    public ApexAPIResult compare(final String otherModelFileName, final boolean diffsOnly, final boolean keysOnly) {
+        return modelHandlerFacade.compare(otherModelFileName, diffsOnly, keysOnly);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.core.modelapi.ApexModel#compareWithString(java.lang.String,
+     * boolean, boolean)
+     */
+    @Override
+    public ApexAPIResult compareWithString(final String otherModelString, final boolean diffsOnly,
+            final boolean keysOnly) {
+        return modelHandlerFacade.compareWithString(otherModelString, diffsOnly, keysOnly);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexModel#split(java.lang.String, java.lang.String)
+     */
+    @Override
+    public ApexAPIResult split(final String targetModelFileName, final String splitOutPolicies) {
+        return modelHandlerFacade.split(targetModelFileName, splitOutPolicies);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.core.modelapi.ApexModel#split(java.lang.String)
+     */
+    @Override
+    public ApexAPIResult split(final String splitOutPolicies) {
+        return modelHandlerFacade.split(splitOutPolicies);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexModel#merge(java.lang.String, boolean)
+     */
+    @Override
+    public ApexAPIResult merge(final String mergeInModelFileName, final boolean keepOriginal) {
+        return modelHandlerFacade.merge(mergeInModelFileName, keepOriginal);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.core.modelapi.ApexModel#mergeWithString(java.lang.String, boolean)
+     */
+    @Override
+    public ApexAPIResult mergeWithString(final String otherModelString, final boolean keepOriginal) {
+        return modelHandlerFacade.mergeWithString(otherModelString, keepOriginal);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        final int prime = HASH_CODE_PRIME_0;
+        int result = 1;
+        result = prime * result + ((apexProperties == null) ? 0 : apexProperties.hashCode());
+        result = prime * result + ((contextAlbumFacade == null) ? 0 : contextAlbumFacade.hashCode());
+        result = prime * result + ((contextSchemaFacade == null) ? 0 : contextSchemaFacade.hashCode());
+        result = prime * result + ((eventFacade == null) ? 0 : eventFacade.hashCode());
+        result = prime * result + ((fileName == null) ? 0 : fileName.hashCode());
+        result = prime * result + (jsonMode ? HASH_CODE_PRIME_1 : HASH_CODE_PRIME_2);
+        result = prime * result + ((keyInformationFacade == null) ? 0 : keyInformationFacade.hashCode());
+        result = prime * result + ((modelFacade == null) ? 0 : modelFacade.hashCode());
+        result = prime * result + ((modelHandlerFacade == null) ? 0 : modelHandlerFacade.hashCode());
+        result = prime * result + ((policyFacade == null) ? 0 : policyFacade.hashCode());
+        result = prime * result + ((policyModel == null) ? 0 : policyModel.hashCode());
+        result = prime * result + ((taskFacade == null) ? 0 : taskFacade.hashCode());
+        return result;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.auth.api.ApexModel#getModel()
+     */
+    @Override
+    public AxPolicyModel getPolicyModel() {
+        return policyModel;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see
+     * org.onap.policy.apex.auth.api.ApexModel#setPolicyModel(org.onap.policy.apex.core.policymodel.
+     * concepts.AxPolicyModel)
+     */
+    @Override
+    public void setPolicyModel(final AxPolicyModel policyModel) {
+        this.policyModel = policyModel;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.core.modelapi.ApexModel#build()
+     */
+    @Override
+    public AxPolicyModel build() {
+        return policyModel;
+    }
+
+}
diff --git a/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/impl/ContextAlbumFacade.java b/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/impl/ContextAlbumFacade.java
new file mode 100644
index 0000000..57d0502
--- /dev/null
+++ b/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/impl/ContextAlbumFacade.java
@@ -0,0 +1,282 @@
+/*-
+ * ============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.model.modelapi.impl;
+
+import java.util.Properties;
+import java.util.Set;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelStringWriter;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+import org.onap.policy.apex.model.modelapi.ApexAPIResult;
+import org.onap.policy.apex.model.modelapi.ApexModel;
+
+/**
+ * This class acts as a facade for operations towards a policy model for context album operations.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ContextAlbumFacade {
+    private static final String CONCEPT = "concept ";
+    private static final String CONCEPT_S = "concept(s) ";
+    private static final String DOES_NOT_EXIST = " does not exist";
+    private static final String DO_ES_NOT_EXIST = " do(es) not exist";
+
+    // Apex model we're working towards
+    private final ApexModel apexModel;
+
+    // Properties to use for the model
+    private final Properties apexProperties;
+
+    // Facade classes for working towards the real Apex model
+    private final KeyInformationFacade keyInformationFacade;
+
+    // JSON output on list/delete if set
+    private final boolean jsonMode;
+
+    /**
+     * Constructor that creates a context album facade for the Apex Model API.
+     *
+     * @param apexModel the apex model
+     * @param apexProperties Properties for the model
+     * @param jsonMode set to true to return JSON strings in list and delete operations, otherwise
+     *        set to false
+     */
+    public ContextAlbumFacade(final ApexModel apexModel, final Properties apexProperties, final boolean jsonMode) {
+        this.apexModel = apexModel;
+        this.apexProperties = apexProperties;
+        this.jsonMode = jsonMode;
+
+        keyInformationFacade = new KeyInformationFacade(apexModel, apexProperties, jsonMode);
+    }
+
+    /**
+     * Create a context album.
+     *
+     * @param name name of the context album
+     * @param version version of the context album, set to null to use the default version
+     * @param scope of the context album
+     * @param writable "true" or "t" if the context album is writable, set to null or any other
+     *        value for a read-only album
+     * @param contextSchemaName name of the parameter context schema
+     * @param contextSchemaVersion version of the parameter context schema, set to null to use the
+     *        latest version
+     * @param uuid context album UUID, set to null to generate a UUID
+     * @param description context album description, set to null to generate a description
+     * @return result of the operation
+     */
+    // CHECKSTYLE:OFF: checkstyle:parameterNumber
+    public ApexAPIResult createContextAlbum(final String name, final String version, final String scope,
+            final String writable, final String contextSchemaName, final String contextSchemaVersion, final String uuid,
+            final String description) {
+        try {
+            final AxArtifactKey key = new AxArtifactKey();
+            key.setName(name);
+            if (version != null) {
+                key.setVersion(version);
+            } else {
+                key.setVersion(apexProperties.getProperty("DEFAULT_CONCEPT_VERSION"));
+            }
+
+            if (apexModel.getPolicyModel().getAlbums().getAlbumsMap().containsKey(key)) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_EXISTS,
+                        CONCEPT + key.getID() + " already exists");
+            }
+
+            final AxContextSchema schema =
+                    apexModel.getPolicyModel().getSchemas().get(contextSchemaName, contextSchemaVersion);
+            if (schema == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + contextSchemaName + ':' + contextSchemaVersion + DOES_NOT_EXIST);
+            }
+
+            final AxContextAlbum contextAlbum = new AxContextAlbum(key);
+            contextAlbum.setScope(scope);
+            contextAlbum.setItemSchema(schema.getKey());
+
+            if (writable != null
+                    && (writable.trim().equalsIgnoreCase("true") || writable.trim().equalsIgnoreCase("t"))) {
+                contextAlbum.setWritable(true);
+            } else {
+                contextAlbum.setWritable(false);
+            }
+
+            apexModel.getPolicyModel().getAlbums().getAlbumsMap().put(key, contextAlbum);
+
+            if (apexModel.getPolicyModel().getKeyInformation().getKeyInfoMap().containsKey(key)) {
+                return keyInformationFacade.updateKeyInformation(name, version, uuid, description);
+            } else {
+                return keyInformationFacade.createKeyInformation(name, version, uuid, description);
+            }
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+    // CHECKSTYLE:ON: checkstyle:parameterNumber
+
+    /**
+     * Update a context album.
+     *
+     * @param name name of the context album
+     * @param version version of the context album, set to null to use the default version
+     * @param scope of the context album
+     * @param writable "true" or "t" if the context album is writable, set to null or any other
+     *        value for a read-only album
+     * @param contextSchemaName name of the parameter context schema
+     * @param contextSchemaVersion version of the parameter context schema, set to null to use the
+     *        latest version
+     * @param uuid context album UUID, set to null to generate a UUID
+     * @param description context album description, set to null to generate a description
+     * @return result of the operation
+     */
+    // CHECKSTYLE:OFF: checkstyle:parameterNumber
+    public ApexAPIResult updateContextAlbum(final String name, final String version, final String scope,
+            final String writable, final String contextSchemaName, final String contextSchemaVersion, final String uuid,
+            final String description) {
+        try {
+            final AxContextAlbum contextAlbum = apexModel.getPolicyModel().getAlbums().get(name, version);
+            if (contextAlbum == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            if (scope != null) {
+                contextAlbum.setScope(scope);
+            }
+            if (writable != null) {
+                if (writable.trim().equalsIgnoreCase("true") || writable.trim().equalsIgnoreCase("t")) {
+                    contextAlbum.setWritable(true);
+                } else {
+                    contextAlbum.setWritable(false);
+                }
+            }
+
+            if (contextSchemaName != null) {
+                final AxContextSchema schema =
+                        apexModel.getPolicyModel().getSchemas().get(contextSchemaName, contextSchemaVersion);
+                if (schema == null) {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            CONCEPT + contextSchemaName + ':' + contextSchemaVersion + DOES_NOT_EXIST);
+                }
+                contextAlbum.setItemSchema(schema.getKey());
+            }
+
+            return keyInformationFacade.updateKeyInformation(name, version, uuid, description);
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+    // CHECKSTYLE:ON: checkstyle:parameterNumber
+
+    /**
+     * List context albums.
+     *
+     * @param name name of the context album, set to null to list all
+     * @param version starting version of the context album, set to null to list all versions
+     * @return result of the operation
+     */
+    public ApexAPIResult listContextAlbum(final String name, final String version) {
+        try {
+            final Set<AxContextAlbum> contextAlbumSet = apexModel.getPolicyModel().getAlbums().getAll(name, version);
+            if (name != null && contextAlbumSet.isEmpty()) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
+            }
+
+            final ApexAPIResult result = new ApexAPIResult();
+            for (final AxContextAlbum contextAlbum : contextAlbumSet) {
+                result.addMessage(new ApexModelStringWriter<AxContextAlbum>(false).writeString(contextAlbum,
+                        AxContextAlbum.class, jsonMode));
+            }
+            return result;
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Delete a context album.
+     *
+     * @param name name of the context album
+     * @param version version of the context album, set to null to delete versions
+     * @return result of the operation
+     */
+    public ApexAPIResult deleteContextAlbum(final String name, final String version) {
+        try {
+            if (version != null) {
+                final AxArtifactKey key = new AxArtifactKey(name, version);
+                if (apexModel.getPolicyModel().getAlbums().getAlbumsMap().remove(key) != null) {
+                    return new ApexAPIResult();
+                } else {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            CONCEPT + key.getID() + DOES_NOT_EXIST);
+                }
+            }
+
+            final Set<AxContextAlbum> contextAlbumSet = apexModel.getPolicyModel().getAlbums().getAll(name, version);
+            if (contextAlbumSet.isEmpty()) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
+            }
+
+            final ApexAPIResult result = new ApexAPIResult();
+            for (final AxContextAlbum contextAlbum : contextAlbumSet) {
+                result.addMessage(new ApexModelStringWriter<AxContextAlbum>(false).writeString(contextAlbum,
+                        AxContextAlbum.class, jsonMode));
+                apexModel.getPolicyModel().getAlbums().getAlbumsMap().remove(contextAlbum.getKey());
+                keyInformationFacade.deleteKeyInformation(name, version);
+            }
+            return result;
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Validate context albums.
+     *
+     * @param name name of the context album, set to null to list all
+     * @param version starting version of the context album, set to null to list all versions
+     * @return result of the operation
+     */
+    public ApexAPIResult validateContextAlbum(final String name, final String version) {
+        try {
+            final Set<AxContextAlbum> contextAlbumSet = apexModel.getPolicyModel().getAlbums().getAll(name, version);
+            if (contextAlbumSet.isEmpty()) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
+            }
+
+            final ApexAPIResult result = new ApexAPIResult();
+            for (final AxContextAlbum contextAlbum : contextAlbumSet) {
+                final AxValidationResult validationResult = contextAlbum.validate(new AxValidationResult());
+                result.addMessage(new ApexModelStringWriter<AxArtifactKey>(false).writeString(contextAlbum.getKey(),
+                        AxArtifactKey.class, jsonMode));
+                result.addMessage(validationResult.toString());
+            }
+            return result;
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+}
diff --git a/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/impl/ContextSchemaFacade.java b/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/impl/ContextSchemaFacade.java
new file mode 100644
index 0000000..3f7f756
--- /dev/null
+++ b/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/impl/ContextSchemaFacade.java
@@ -0,0 +1,240 @@
+/*-
+ * ============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.model.modelapi.impl;
+
+import java.util.Properties;
+import java.util.Set;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelStringWriter;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+import org.onap.policy.apex.model.modelapi.ApexAPIResult;
+import org.onap.policy.apex.model.modelapi.ApexModel;
+import org.onap.policy.apex.model.utilities.Assertions;
+
+/**
+ * This class acts as a facade for operations towards a policy model for context schema operations.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ContextSchemaFacade {
+	private static final String CONCEPT = "concept ";
+	private static final String CONCEPT_S = "concept(s) ";
+    private static final String DOES_NOT_EXIST = " does not exist";
+	private static final String DO_ES_NOT_EXIST = " do(es) not exist";
+	private static final String ALREADY_EXISTS = " already exists";
+
+	// Apex model we're working towards
+    private final ApexModel apexModel;
+
+    // Properties to use for the model
+    private final Properties apexProperties;
+
+    // Facade classes for working towards the real Apex model
+    private final KeyInformationFacade keyInformationFacade;
+
+    // JSON output on list/delete if set
+    private final boolean jsonMode;
+
+    /**
+     * Constructor to create the context schema facade for the Model API.
+     *
+     * @param apexModel the apex model
+     * @param apexProperties Properties for the model
+     * @param jsonMode set to true to return JSON strings in list and delete operations, otherwise set to false
+     */
+    public ContextSchemaFacade(final ApexModel apexModel, final Properties apexProperties, final boolean jsonMode) {
+        this.apexModel = apexModel;
+        this.apexProperties = apexProperties;
+        this.jsonMode = jsonMode;
+
+        keyInformationFacade = new KeyInformationFacade(apexModel, apexProperties, jsonMode);
+    }
+
+    /**
+     * Create a context schema.
+     *
+     * @param name name of the context schema
+     * @param version version of the context schema, set to null to use the default version
+     * @param schemaFlavour a string identifying the flavour of this context schema
+     * @param schemaDefinition a string containing the definition of this context schema
+     * @param uuid context schema UUID, set to null to generate a UUID
+     * @param description context schema description, set to null to generate a description
+     * @return result of the operation
+     */
+    public ApexAPIResult createContextSchema(final String name, final String version, final String schemaFlavour, final String schemaDefinition,
+            final String uuid, final String description) {
+        try {
+            Assertions.argumentNotNull(schemaFlavour, "schemaFlavour may not be null");
+
+            final AxArtifactKey key = new AxArtifactKey();
+            key.setName(name);
+            if (version != null) {
+                key.setVersion(version);
+            }
+            else {
+                key.setVersion(apexProperties.getProperty("DEFAULT_CONCEPT_VERSION"));
+            }
+
+            if (apexModel.getPolicyModel().getSchemas().getSchemasMap().containsKey(key)) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_EXISTS, CONCEPT + key.getID() + ALREADY_EXISTS);
+            }
+
+            apexModel.getPolicyModel().getSchemas().getSchemasMap().put(key, new AxContextSchema(key, schemaFlavour, schemaDefinition));
+
+            if (apexModel.getPolicyModel().getKeyInformation().getKeyInfoMap().containsKey(key)) {
+                return keyInformationFacade.updateKeyInformation(name, version, uuid, description);
+            }
+            else {
+                return keyInformationFacade.createKeyInformation(name, version, uuid, description);
+            }
+        }
+        catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Update a context schema.
+     *
+     * @param name name of the context schema
+     * @param version version of the context schema, set to null to update the latest version
+     * @param schemaFlavour a string identifying the flavour of this context schema
+     * @param schemaDefinition a string containing the definition of this context schema
+     * @param uuid context schema UUID, set to null to not update
+     * @param description context schema description, set to null to not update
+     * @return result of the operation
+     */
+    public ApexAPIResult updateContextSchema(final String name, final String version, final String schemaFlavour, final String schemaDefinition,
+            final String uuid, final String description) {
+        try {
+            final AxContextSchema schema = apexModel.getPolicyModel().getSchemas().get(name, version);
+            if (schema == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST, CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            if (schemaFlavour != null) {
+                schema.setSchemaFlavour(schemaFlavour);
+            }
+
+            if (schemaDefinition != null) {
+                schema.setSchema(schemaDefinition);
+            }
+
+            return keyInformationFacade.updateKeyInformation(name, version, uuid, description);
+        }
+        catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * List context schemas.
+     *
+     * @param name name of the context schema, set to null to list all
+     * @param version starting version of the context schema, set to null to list all versions
+     * @return result of the operation
+     */
+    public ApexAPIResult listContextSchemas(final String name, final String version) {
+        try {
+            final Set<AxContextSchema> schemaSet = apexModel.getPolicyModel().getSchemas().getAll(name, version);
+            if (name != null && schemaSet.isEmpty()) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST, CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
+            }
+
+            final ApexAPIResult result = new ApexAPIResult();
+            for (final AxContextSchema schema : schemaSet) {
+                result.addMessage(new ApexModelStringWriter<AxContextSchema>(false).writeString(schema, AxContextSchema.class, jsonMode));
+            }
+            return result;
+        }
+        catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Delete a context schema.
+     *
+     * @param name name of the context schema
+     * @param version version of the context schema, set to null to delete all versions
+     * @return result of the operation
+     */
+    public ApexAPIResult deleteContextSchema(final String name, final String version) {
+        try {
+            if (version != null) {
+                final AxArtifactKey key = new AxArtifactKey(name, version);
+                final AxContextSchema removedSchema = apexModel.getPolicyModel().getSchemas().getSchemasMap().remove(key);
+                if (removedSchema != null) {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.SUCCESS,
+                            new ApexModelStringWriter<AxContextSchema>(false).writeString(removedSchema, AxContextSchema.class, jsonMode));
+                }
+                else {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST, CONCEPT + key.getID() + DOES_NOT_EXIST);
+                }
+            }
+
+            final Set<AxContextSchema> schemaSet = apexModel.getPolicyModel().getSchemas().getAll(name, version);
+            if (schemaSet.isEmpty()) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST, CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
+            }
+
+            final ApexAPIResult result = new ApexAPIResult();
+            for (final AxContextSchema schema : schemaSet) {
+                result.addMessage(new ApexModelStringWriter<AxContextSchema>(false).writeString(schema, AxContextSchema.class, jsonMode));
+                apexModel.getPolicyModel().getSchemas().getSchemasMap().remove(schema.getKey());
+                keyInformationFacade.deleteKeyInformation(name, version);
+            }
+            return result;
+        }
+        catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Validate context schemas.
+     *
+     * @param name name of the context schema, set to null to list all
+     * @param version starting version of the context schema, set to null to list all versions
+     * @return result of the operation
+     */
+    public ApexAPIResult validateContextSchemas(final String name, final String version) {
+        try {
+            final Set<AxContextSchema> schemaSet = apexModel.getPolicyModel().getSchemas().getAll(name, version);
+            if (schemaSet.isEmpty()) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST, CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
+            }
+
+            final ApexAPIResult result = new ApexAPIResult();
+            for (final AxContextSchema schema : schemaSet) {
+                final AxValidationResult validationResult = schema.validate(new AxValidationResult());
+                result.addMessage(new ApexModelStringWriter<AxArtifactKey>(false).writeString(schema.getKey(), AxArtifactKey.class, jsonMode));
+                result.addMessage(validationResult.toString());
+            }
+            return result;
+        }
+        catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+}
diff --git a/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/impl/EventFacade.java b/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/impl/EventFacade.java
new file mode 100644
index 0000000..095d4f9
--- /dev/null
+++ b/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/impl/EventFacade.java
@@ -0,0 +1,385 @@
+/*-
+ * ============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.model.modelapi.impl;
+
+import java.util.Properties;
+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.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelStringWriter;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+import org.onap.policy.apex.model.eventmodel.concepts.AxEvent;
+import org.onap.policy.apex.model.eventmodel.concepts.AxField;
+import org.onap.policy.apex.model.modelapi.ApexAPIResult;
+import org.onap.policy.apex.model.modelapi.ApexModel;
+import org.onap.policy.apex.model.utilities.Assertions;
+
+/**
+ * This class acts as a facade for operations towards a policy model for event operations
+ * operations.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class EventFacade {
+    private static final String CONCEPT = "concept ";
+    private static final String CONCEPT_S = "concept(s) ";
+    private static final String DOES_NOT_EXIST = " does not exist";
+    private static final String DO_ES_NOT_EXIST = " do(es) not exist";
+    private static final String ALREADY_EXISTS = " already exists";
+
+    // Apex model we're working towards
+    private final ApexModel apexModel;
+
+    // Properties to use for the model
+    private final Properties apexProperties;
+
+    // Facade classes for working towards the real Apex model
+    private final KeyInformationFacade keyInformationFacade;
+
+    // JSON output on list/delete if set
+    private final boolean jsonMode;
+
+    /**
+     * Constructor to create an event facade for the Model API.
+     *
+     * @param apexModel the apex model
+     * @param apexProperties Properties for the model
+     * @param jsonMode set to true to return JSON strings in list and delete operations, otherwise
+     *        set to false
+     */
+    public EventFacade(final ApexModel apexModel, final Properties apexProperties, final boolean jsonMode) {
+        this.apexModel = apexModel;
+        this.apexProperties = apexProperties;
+        this.jsonMode = jsonMode;
+
+        keyInformationFacade = new KeyInformationFacade(apexModel, apexProperties, jsonMode);
+    }
+
+    /**
+     * Create an event.
+     *
+     * @param name name of the event
+     * @param version version of the event, set to null to use the default version
+     * @param nameSpace of the event, set to null to use the default value
+     * @param source of the event, set to null to use the default value
+     * @param target of the event, set to null to use the default value
+     * @param uuid event UUID, set to null to generate a UUID
+     * @param description event description, set to null to generate a description
+     * @return result of the operation
+     */
+    public ApexAPIResult createEvent(final String name, final String version, final String nameSpace,
+            final String source, final String target, final String uuid, final String description) {
+        try {
+            final AxArtifactKey key = new AxArtifactKey();
+            key.setName(name);
+            if (version != null) {
+                key.setVersion(version);
+            } else {
+                key.setVersion(apexProperties.getProperty("DEFAULT_CONCEPT_VERSION"));
+            }
+
+            if (apexModel.getPolicyModel().getEvents().getEventMap().containsKey(key)) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_EXISTS, CONCEPT + key.getID() + ALREADY_EXISTS);
+            }
+
+            final AxEvent event = new AxEvent(key);
+
+            event.setNameSpace((nameSpace != null ? nameSpace : apexProperties.getProperty("DEFAULT_EVENT_NAMESPACE")));
+            event.setSource((source != null ? source : apexProperties.getProperty("DEFAULT_EVENT_SOURCE")));
+            event.setTarget((target != null ? target : apexProperties.getProperty("DEFAULT_EVENT_TARGET")));
+
+            apexModel.getPolicyModel().getEvents().getEventMap().put(key, event);
+
+            if (apexModel.getPolicyModel().getKeyInformation().getKeyInfoMap().containsKey(key)) {
+                return keyInformationFacade.updateKeyInformation(name, version, uuid, description);
+            } else {
+                return keyInformationFacade.createKeyInformation(name, version, uuid, description);
+            }
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Update an event.
+     *
+     * @param name name of the event
+     * @param version version of the event, set to null to use the latest version
+     * @param nameSpace of the event, set to null to not update
+     * @param source of the event, set to null to not update
+     * @param target of the event, set to null to not update
+     * @param uuid event UUID, set to null to not update
+     * @param description event description, set to null to not update
+     * @return result of the operation
+     */
+    public ApexAPIResult updateEvent(final String name, final String version, final String nameSpace,
+            final String source, final String target, final String uuid, final String description) {
+        try {
+            final AxEvent event = apexModel.getPolicyModel().getEvents().get(name, version);
+            if (event == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            if (nameSpace != null) {
+                event.setNameSpace(nameSpace);
+            }
+            if (source != null) {
+                event.setSource(source);
+            }
+            if (target != null) {
+                event.setTarget(target);
+            }
+
+            return keyInformationFacade.updateKeyInformation(name, version, uuid, description);
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * List events.
+     *
+     * @param name name of the event, set to null to list all
+     * @param version starting version of the event, set to null to list all versions
+     * @return result of the operation
+     */
+    public ApexAPIResult listEvent(final String name, final String version) {
+        try {
+            final Set<AxEvent> eventSet = apexModel.getPolicyModel().getEvents().getAll(name, version);
+            if (name != null && eventSet.isEmpty()) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
+            }
+
+            final ApexAPIResult result = new ApexAPIResult();
+            for (final AxEvent event : eventSet) {
+                result.addMessage(
+                        new ApexModelStringWriter<AxEvent>(false).writeString(event, AxEvent.class, jsonMode));
+            }
+            return result;
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Delete an event.
+     *
+     * @param name name of the event
+     * @param version version of the event, set to null to delete all versions
+     * @return result of the operation
+     */
+    public ApexAPIResult deleteEvent(final String name, final String version) {
+        try {
+            if (version != null) {
+                final AxArtifactKey key = new AxArtifactKey(name, version);
+                final AxEvent removedEvent = apexModel.getPolicyModel().getEvents().getEventMap().remove(key);
+                if (removedEvent != null) {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.SUCCESS, new ApexModelStringWriter<AxEvent>(false)
+                            .writeString(removedEvent, AxEvent.class, jsonMode));
+                } else {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            CONCEPT + key.getID() + DOES_NOT_EXIST);
+                }
+            }
+
+            final Set<AxEvent> eventSet = apexModel.getPolicyModel().getEvents().getAll(name, version);
+            if (eventSet.isEmpty()) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
+            }
+
+            final ApexAPIResult result = new ApexAPIResult();
+            for (final AxEvent event : eventSet) {
+                result.addMessage(
+                        new ApexModelStringWriter<AxEvent>(false).writeString(event, AxEvent.class, jsonMode));
+                apexModel.getPolicyModel().getEvents().getEventMap().remove(event.getKey());
+                keyInformationFacade.deleteKeyInformation(name, version);
+            }
+            return result;
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Validate events.
+     *
+     * @param name name of the event, set to null to list all
+     * @param version starting version of the event, set to null to list all versions
+     * @return result of the operation
+     */
+    public ApexAPIResult validateEvent(final String name, final String version) {
+        try {
+            final Set<AxEvent> eventSet = apexModel.getPolicyModel().getEvents().getAll(name, version);
+            if (eventSet.isEmpty()) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
+            }
+
+            final ApexAPIResult result = new ApexAPIResult();
+            for (final AxEvent event : eventSet) {
+                final AxValidationResult validationResult = event.validate(new AxValidationResult());
+                result.addMessage(new ApexModelStringWriter<AxArtifactKey>(false).writeString(event.getKey(),
+                        AxArtifactKey.class, jsonMode));
+                result.addMessage(validationResult.toString());
+            }
+            return result;
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Create an event parameter.
+     *
+     * @param name name of the event
+     * @param version version of the event, set to null to use the latest version
+     * @param parName of the parameter
+     * @param contextSchemaName name of the parameter context schema
+     * @param contextSchemaVersion version of the parameter context schema, set to null to use the
+     *        latest version
+     * @param optional true if the event parameter is optional, false otherwise
+     * @return result of the operation
+     */
+    public ApexAPIResult createEventPar(final String name, final String version, final String parName,
+            final String contextSchemaName, final String contextSchemaVersion, final boolean optional) {
+        try {
+            Assertions.argumentNotNull(parName, "parName may not be null");
+
+            final AxEvent event = apexModel.getPolicyModel().getEvents().get(name, version);
+            if (event == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            final AxReferenceKey refKey = new AxReferenceKey(event.getKey(), parName);
+
+            if (event.getParameterMap().containsKey(refKey.getLocalName())) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_EXISTS,
+                        CONCEPT + refKey.getID() + ALREADY_EXISTS);
+            }
+
+            final AxContextSchema schema =
+                    apexModel.getPolicyModel().getSchemas().get(contextSchemaName, contextSchemaVersion);
+            if (schema == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + contextSchemaName + ':' + contextSchemaVersion + DOES_NOT_EXIST);
+            }
+
+            event.getParameterMap().put(refKey.getLocalName(), new AxField(refKey, schema.getKey(), optional));
+            return new ApexAPIResult();
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * List event parameters.
+     *
+     * @param name name of the event
+     * @param version version of the event, set to null to list latest version
+     * @param parName name of the parameter, set to null to list all parameters of the event
+     * @return result of the operation
+     */
+    public ApexAPIResult listEventPar(final String name, final String version, final String parName) {
+        try {
+            final AxEvent event = apexModel.getPolicyModel().getEvents().get(name, version);
+            if (event == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            if (parName != null) {
+                final AxField eventField = event.getParameterMap().get(parName);
+                if (eventField != null) {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.SUCCESS,
+                            new ApexModelStringWriter<AxField>(false).writeString(eventField, AxField.class, jsonMode));
+                } else {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            CONCEPT + name + ':' + version + ':' + parName + DOES_NOT_EXIST);
+                }
+            } else {
+                if (event.getParameterMap().size() == 0) {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            "no parameters defined on event " + event.getKey().getID());
+                }
+
+                final ApexAPIResult result = new ApexAPIResult();
+                for (final AxField eventPar : event.getParameterMap().values()) {
+                    result.addMessage(
+                            new ApexModelStringWriter<AxField>(false).writeString(eventPar, AxField.class, jsonMode));
+                }
+                return result;
+            }
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Delete an event parameter.
+     *
+     * @param name name of the event
+     * @param version version of the event, set to null to use the latest version
+     * @param parName of the parameter, set to null to delete all parameters
+     * @return result of the operation
+     */
+    public ApexAPIResult deleteEventPar(final String name, final String version, final String parName) {
+        try {
+            final AxEvent event = apexModel.getPolicyModel().getEvents().get(name, version);
+            if (event == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            final ApexAPIResult result = new ApexAPIResult();
+            if (parName != null) {
+                if (event.getParameterMap().containsKey(parName)) {
+                    result.addMessage(new ApexModelStringWriter<AxField>(false)
+                            .writeString(event.getParameterMap().get(parName), AxField.class, jsonMode));
+                    event.getParameterMap().remove(parName);
+                    return result;
+                } else {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            CONCEPT + name + ':' + version + ':' + parName + DOES_NOT_EXIST);
+                }
+            } else {
+                if (event.getParameterMap().size() == 0) {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            "no parameters defined on event " + event.getKey().getID());
+                }
+
+                for (final AxField eventPar : event.getParameterMap().values()) {
+                    result.addMessage(
+                            new ApexModelStringWriter<AxField>(false).writeString(eventPar, AxField.class, jsonMode));
+                }
+                event.getParameterMap().clear();
+                return result;
+            }
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+}
diff --git a/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/impl/KeyInformationFacade.java b/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/impl/KeyInformationFacade.java
new file mode 100644
index 0000000..d9b9cef
--- /dev/null
+++ b/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/impl/KeyInformationFacade.java
@@ -0,0 +1,244 @@
+/*-
+ * ============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.model.modelapi.impl;
+
+import java.util.Properties;
+import java.util.Set;
+import java.util.UUID;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInfo;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelStringWriter;
+import org.onap.policy.apex.model.modelapi.ApexAPIResult;
+import org.onap.policy.apex.model.modelapi.ApexModel;
+
+/**
+ * This class acts as a facade for operations towards a policy model for key information operations.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class KeyInformationFacade {
+    private static final String CONCEPT = "concept ";
+    private static final String CONCEPT_S = "concept(s) ";
+    private static final String DOES_NOT_EXIST = " does not exist";
+    private static final String DO_ES_NOT_EXIST = " do(es) not exist";
+    private static final String ALREADY_EXISTS = " already exists";
+
+    // Apex model we're working towards
+    private final ApexModel apexModel;
+
+    // Properties to use for the model
+    private final Properties apexProperties;
+
+    // JSON output on list/delete if set
+    private final boolean jsonMode;
+
+    /**
+     * Constructor to create a key information facade for the Model API.
+     *
+     * @param apexModel the apex model
+     * @param apexProperties Properties for the model
+     * @param jsonMode set to true to return JSON strings in list and delete operations, otherwise
+     *        set to false
+     */
+    public KeyInformationFacade(final ApexModel apexModel, final Properties apexProperties, final boolean jsonMode) {
+        this.apexModel = apexModel;
+        this.apexProperties = apexProperties;
+        this.jsonMode = jsonMode;
+    }
+
+    /**
+     * Create key information.
+     *
+     * @param name name of the concept for the key information
+     * @param version version of the concept for the key information, set to null to use the default
+     *        version
+     * @param uuid key information UUID, set to null to generate a UUID
+     * @param description key information description, set to null to generate a description
+     * @return result of the operation
+     */
+    public ApexAPIResult createKeyInformation(final String name, final String version, final String uuid,
+            final String description) {
+        try {
+            final AxArtifactKey key = new AxArtifactKey();
+            key.setName(name);
+            if (version != null) {
+                key.setVersion(version);
+            } else {
+                key.setVersion(apexProperties.getProperty("DEFAULT_CONCEPT_VERSION"));
+            }
+
+            if (apexModel.getPolicyModel().getKeyInformation().getKeyInfoMap().containsKey(key)) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_EXISTS, CONCEPT + key.getID() + ALREADY_EXISTS);
+            }
+
+            final AxKeyInfo keyInfo = new AxKeyInfo(key);
+            if (description != null) {
+                keyInfo.setDescription(description);
+            }
+            if (uuid != null) {
+                keyInfo.setUuid(UUID.fromString(uuid));
+            } else {
+                // generate a reproducible UUID
+                keyInfo.setUuid(AxKeyInfo.generateReproducibleUUID(keyInfo.getID() + keyInfo.getDescription()));
+            }
+            apexModel.getPolicyModel().getKeyInformation().getKeyInfoMap().put(key, keyInfo);
+            return new ApexAPIResult();
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Update key information.
+     *
+     * @param name name of the concept for the key information
+     * @param version version of the concept for the key information, set to null to update the
+     *        latest version
+     * @param uuid key information UUID, set to null to not update
+     * @param description key information description, set to null to not update
+     * @return result of the operation
+     */
+    public ApexAPIResult updateKeyInformation(final String name, final String version, final String uuid,
+            final String description) {
+        try {
+            final AxKeyInfo keyInfo = apexModel.getPolicyModel().getKeyInformation().get(name, version);
+            if (keyInfo == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ":" + version + DOES_NOT_EXIST);
+            }
+
+            if (description != null) {
+                keyInfo.setDescription(description);
+            }
+
+            if (uuid != null) {
+                keyInfo.setUuid(UUID.fromString(uuid));
+            } else {
+                // generate a reproducible UUID
+                keyInfo.setUuid(AxKeyInfo.generateReproducibleUUID(keyInfo.getID() + keyInfo.getDescription()));
+            }
+
+            return new ApexAPIResult();
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * List key information.
+     *
+     * @param name name of the concept for the key information, set to null to list all
+     * @param version starting version of the concept for the key information, set to null to list
+     *        all versions
+     * @return result of the operation
+     */
+    public ApexAPIResult listKeyInformation(final String name, final String version) {
+        try {
+            final Set<AxKeyInfo> keyInfoSet = apexModel.getPolicyModel().getKeyInformation().getAll(name, version);
+            if (name != null && keyInfoSet.isEmpty()) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
+            }
+
+            final ApexAPIResult result = new ApexAPIResult();
+            for (final AxKeyInfo keyInfo : keyInfoSet) {
+                result.addMessage(
+                        new ApexModelStringWriter<AxKeyInfo>(false).writeString(keyInfo, AxKeyInfo.class, jsonMode));
+            }
+            return result;
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Delete key information.
+     *
+     * @param name name of the concept for the key information
+     * @param version version of the concept for the key information, set to null to delete all
+     *        versions
+     * @return result of the operation
+     */
+    public ApexAPIResult deleteKeyInformation(final String name, final String version) {
+        try {
+            if (version != null) {
+                final AxArtifactKey key = new AxArtifactKey(name, version);
+                final AxKeyInfo removedKeyInfo =
+                        apexModel.getPolicyModel().getKeyInformation().getKeyInfoMap().remove(key);
+                if (removedKeyInfo != null) {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.SUCCESS, new ApexModelStringWriter<AxKeyInfo>(false)
+                            .writeString(removedKeyInfo, AxKeyInfo.class, jsonMode));
+                } else {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            CONCEPT + key.getID() + DOES_NOT_EXIST);
+                }
+            }
+
+            final Set<AxKeyInfo> keyInfoSet = apexModel.getPolicyModel().getKeyInformation().getAll(name, version);
+            if (keyInfoSet.isEmpty()) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
+            }
+
+            final ApexAPIResult result = new ApexAPIResult();
+            for (final AxKeyInfo keyInfo : keyInfoSet) {
+                result.addMessage(
+                        new ApexModelStringWriter<AxKeyInfo>(false).writeString(keyInfo, AxKeyInfo.class, jsonMode));
+                apexModel.getPolicyModel().getKeyInformation().getKeyInfoMap().remove(keyInfo.getKey());
+            }
+            return result;
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Validate key information.
+     *
+     * @param name name of the concept for the key information
+     * @param version version of the concept for the key information, set to null to validate all
+     *        versions
+     * @return result of the operation
+     */
+    public ApexAPIResult validateKeyInformation(final String name, final String version) {
+        try {
+            final Set<AxKeyInfo> keyInfoSet = apexModel.getPolicyModel().getKeyInformation().getAll(name, version);
+            if (keyInfoSet.isEmpty()) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
+            }
+
+            final ApexAPIResult result = new ApexAPIResult();
+            for (final AxKeyInfo keyInfo : keyInfoSet) {
+                final AxValidationResult validationResult = keyInfo.validate(new AxValidationResult());
+                result.addMessage(new ApexModelStringWriter<AxArtifactKey>(false).writeString(keyInfo.getKey(),
+                        AxArtifactKey.class, jsonMode));
+                result.addMessage(validationResult.toString());
+            }
+            return result;
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+}
diff --git a/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/impl/ModelFacade.java b/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/impl/ModelFacade.java
new file mode 100644
index 0000000..2a6dd3e
--- /dev/null
+++ b/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/impl/ModelFacade.java
@@ -0,0 +1,207 @@
+/*-
+ * ============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.model.modelapi.impl;
+
+import java.util.Properties;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelStringWriter;
+import org.onap.policy.apex.model.modelapi.ApexAPIResult;
+import org.onap.policy.apex.model.modelapi.ApexModel;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+import org.onap.policy.apex.model.utilities.Assertions;
+
+/**
+ * This class acts as a facade for operations towards a policy model.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ModelFacade {
+    private static final String CONCEPT = "concept ";
+    private static final String DOES_NOT_EXIST = " does not exist";
+    private static final String ALREADY_CREATED = " already created";
+    private static final String NO_VERSION_SPECIFIED = ", no version specified";
+
+    // Apex model we're working towards
+    private final ApexModel apexModel;
+
+    // Properties to use for the model
+    private final Properties apexProperties;
+
+    // Facade classes for working towards the real Apex model
+    private final KeyInformationFacade keyInformationFacade;
+
+    // JSON output on list/delete if set
+    private final boolean jsonMode;
+
+    /**
+     * Constructor to create a model facade for the Apex model.
+     *
+     * @param apexModel the apex model
+     * @param apexProperties Properties for the model
+     * @param jsonMode set to true to return JSON strings in list and delete operations, otherwise
+     *        set to false
+     */
+    public ModelFacade(final ApexModel apexModel, final Properties apexProperties, final boolean jsonMode) {
+        Assertions.argumentNotNull(apexModel, "apexModel may not be null");
+        Assertions.argumentNotNull(apexProperties, "apexProperties may not be null");
+
+        this.apexModel = apexModel;
+        this.apexProperties = apexProperties;
+        this.jsonMode = jsonMode;
+
+        keyInformationFacade = new KeyInformationFacade(apexModel, apexProperties, jsonMode);
+    }
+
+    /**
+     * Create model.
+     *
+     * @param name name of the model
+     * @param version version of the model, set to null to use the default version
+     * @param uuid model UUID, set to null to generate a UUID
+     * @param description model description, set to null to generate a description
+     * @return result of the operation
+     */
+    public ApexAPIResult createModel(final String name, final String version, final String uuid,
+            final String description) {
+        try {
+            final AxArtifactKey key = new AxArtifactKey();
+            key.setName(name);
+            if (version != null) {
+                key.setVersion(version);
+            } else {
+                final String defaultVersion = apexProperties.getProperty("DEFAULT_CONCEPT_VERSION");
+                if (defaultVersion != null) {
+                    key.setVersion(defaultVersion);
+                } else {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, CONCEPT + name + NO_VERSION_SPECIFIED);
+                }
+            }
+
+            if (!apexModel.getPolicyModel().getKey().equals(AxArtifactKey.getNullKey())) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_EXISTS,
+                        CONCEPT + apexModel.getPolicyModel().getKey().getID() + ALREADY_CREATED);
+            }
+
+            apexModel.setPolicyModel(new AxPolicyModel(key));
+
+            ApexAPIResult result;
+
+            result = keyInformationFacade.createKeyInformation(name, version, uuid, description);
+            if (result.getResult().equals(ApexAPIResult.RESULT.SUCCESS)) {
+                apexModel.getPolicyModel().getKeyInformation().generateKeyInfo(apexModel.getPolicyModel());
+            }
+            return result;
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Update model.
+     *
+     * @param name name of the model
+     * @param version version of the model, set to null to update the latest version
+     * @param uuid key information UUID, set to null to not update
+     * @param description policy description, set to null to not update
+     * @return result of the operation
+     */
+    public ApexAPIResult updateModel(final String name, final String version, final String uuid,
+            final String description) {
+        try {
+            final AxArtifactKey key = new AxArtifactKey();
+            key.setName(name);
+            if (version != null) {
+                key.setVersion(version);
+            } else {
+                final String defaultVersion = apexProperties.getProperty("DEFAULT_CONCEPT_VERSION");
+                if (defaultVersion != null) {
+                    key.setVersion(defaultVersion);
+                } else {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.FAILED,
+                            CONCEPT + apexModel.getPolicyModel().getKey().getID() + NO_VERSION_SPECIFIED);
+                }
+            }
+
+            if (apexModel.getPolicyModel().getKey().equals(AxArtifactKey.getNullKey())) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + apexModel.getPolicyModel().getKey().getID() + DOES_NOT_EXIST);
+            }
+
+            return keyInformationFacade.updateKeyInformation(name, version, uuid, description);
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Get the key of an Apex model.
+     *
+     * @return the result of the operation
+     */
+    public ApexAPIResult getModelKey() {
+        try {
+            final ApexAPIResult result = new ApexAPIResult();
+            final AxArtifactKey modelkey = apexModel.getPolicyModel().getKey();
+            result.addMessage(new ApexModelStringWriter<AxArtifactKey>(false).writeString(modelkey, AxArtifactKey.class,
+                    jsonMode));
+            return result;
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * List an Apex model.
+     *
+     * @return the result of the operation
+     */
+    public ApexAPIResult listModel() {
+        try {
+            final ApexAPIResult result = new ApexAPIResult();
+            result.addMessage(new ApexModelStringWriter<AxPolicyModel>(false).writeString(apexModel.getPolicyModel(),
+                    AxPolicyModel.class, jsonMode));
+            return result;
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Delete an Apex model, clear all the concepts in the model.
+     *
+     * @return the result of the operation
+     */
+    public ApexAPIResult deleteModel() {
+        // @formatter:off
+        apexModel.getPolicyModel().getSchemas()       .getSchemasMap() .clear();
+        apexModel.getPolicyModel().getEvents()        .getEventMap()   .clear();
+        apexModel.getPolicyModel().getAlbums()        .getAlbumsMap()  .clear();
+        apexModel.getPolicyModel().getTasks()         .getTaskMap()    .clear();
+        apexModel.getPolicyModel().getPolicies()      .getPolicyMap()  .clear();
+        apexModel.getPolicyModel().getKeyInformation().getKeyInfoMap() .clear();
+        // @formatter:on
+
+        apexModel.setPolicyModel(new AxPolicyModel());
+
+        return new ApexAPIResult();
+    }
+}
diff --git a/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/impl/ModelHandlerFacade.java b/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/impl/ModelHandlerFacade.java
new file mode 100644
index 0000000..89a656a
--- /dev/null
+++ b/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/impl/ModelHandlerFacade.java
@@ -0,0 +1,630 @@
+/*-
+ * ============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.model.modelapi.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.nio.file.Files;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+
+import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
+import org.onap.policy.apex.model.basicmodel.concepts.ApexRuntimeException;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.dao.ApexDao;
+import org.onap.policy.apex.model.basicmodel.dao.ApexDaoFactory;
+import org.onap.policy.apex.model.basicmodel.dao.DAOParameters;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelException;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelFileWriter;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelReader;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelStringWriter;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelWriter;
+import org.onap.policy.apex.model.modelapi.ApexAPIResult;
+import org.onap.policy.apex.model.modelapi.ApexModel;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicy;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+import org.onap.policy.apex.model.policymodel.handling.PolicyAnalyser;
+import org.onap.policy.apex.model.policymodel.handling.PolicyAnalysisResult;
+import org.onap.policy.apex.model.policymodel.handling.PolicyModelComparer;
+import org.onap.policy.apex.model.policymodel.handling.PolicyModelMerger;
+import org.onap.policy.apex.model.policymodel.handling.PolicyModelSplitter;
+import org.onap.policy.apex.model.utilities.Assertions;
+import org.onap.policy.apex.model.utilities.ResourceUtils;
+import org.onap.policy.apex.model.utilities.TextFileUtils;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * This class acts as a facade for model handling for the Apex Model API.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ModelHandlerFacade {
+    private static final String FOUND_IN_DATABASE = " found in database";
+    private static final String FILE_NAME_MAY_NOT_BE_NULL = "fileName may not be null";
+    private static final String MODEL = "model ";
+    private static final String ALREADY_LOADED = " already loaded";
+
+    private static final XLogger LOGGER = XLoggerFactory.getXLogger(ModelHandlerFacade.class);
+
+    // Apex model we're working towards
+    private final ApexModel apexModel;
+
+    // JSON output on list/delete if set
+    private final boolean jsonMode;
+
+    /**
+     * This Constructor creates a model handling facade for the given {@link ApexModel}.
+     *
+     * @param apexModel the apex model to manipulate
+     * @param apexProperties properties for the model
+     * @param jsonMode set to true to return JSON strings in list and delete operations, otherwise
+     *        set to false
+     */
+    public ModelHandlerFacade(final ApexModel apexModel, final Properties apexProperties, final boolean jsonMode) {
+        Assertions.argumentNotNull(apexModel, "apexModel may not be null");
+        Assertions.argumentNotNull(apexProperties, "apexProperties may not be null");
+
+        this.apexModel = apexModel;
+        this.jsonMode = jsonMode;
+    }
+
+    /**
+     * Load an Apex model from a string.
+     *
+     * @param modelString the string with the model
+     * @return the result of the operation
+     */
+    public ApexAPIResult loadFromString(final String modelString) {
+        Assertions.argumentNotNull(modelString, "modelString may not be null");
+
+        if (!apexModel.getPolicyModel().getKey().equals(AxArtifactKey.getNullKey())) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_EXISTS,
+                    MODEL + apexModel.getPolicyModel().getKey().getID() + ALREADY_LOADED);
+        }
+
+        ApexAPIResult result = new ApexAPIResult();
+        AxPolicyModel newPolicyModel = loadModelFromString(modelString, result);
+        apexModel.setPolicyModel(newPolicyModel != null ? newPolicyModel : new AxPolicyModel());
+
+        return result;
+    }
+
+    /**
+     * Load an Apex model from a file.
+     *
+     * @param fileName the file name of the file with the model
+     * @return the result of the operation
+     */
+    public ApexAPIResult loadFromFile(final String fileName) {
+        Assertions.argumentNotNull(fileName, FILE_NAME_MAY_NOT_BE_NULL);
+
+        if (!apexModel.getPolicyModel().getKey().equals(AxArtifactKey.getNullKey())) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_EXISTS,
+                    MODEL + apexModel.getPolicyModel().getKey().getID() + ALREADY_LOADED);
+        }
+
+        ApexAPIResult result = new ApexAPIResult();
+        AxPolicyModel newPolicyModel = loadModelFromFile(fileName, result);
+        apexModel.setPolicyModel(newPolicyModel != null ? newPolicyModel : new AxPolicyModel());
+
+        return result;
+    }
+
+    /**
+     * Save an Apex model to a file.
+     *
+     * @param fileName the file name
+     * @param xmlFlag if true, save the file in XML format, otherwise save the file in the default
+     *        JSON format
+     * @return the result of the operation
+     */
+    public ApexAPIResult saveToFile(final String fileName, final boolean xmlFlag) {
+        Assertions.argumentNotNull(fileName, FILE_NAME_MAY_NOT_BE_NULL);
+
+        ApexModelFileWriter<AxPolicyModel> apexModelFileWriter = new ApexModelFileWriter<>(false);
+
+        try {
+            if (xmlFlag) {
+                apexModelFileWriter.apexModelWriteXMLFile(apexModel.getPolicyModel(), AxPolicyModel.class, fileName);
+            } else {
+                apexModelFileWriter.apexModelWriteJSONFile(apexModel.getPolicyModel(), AxPolicyModel.class, fileName);
+            }
+            return new ApexAPIResult();
+        } catch (ApexException e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Load an Apex model from a database.
+     *
+     * @param modelName the name of the model to load
+     * @param modelVersion the version of the model to load, loads the policy model from the
+     *        database with this name, if more than one exist, an exception is thrown
+     * @param daoParameters the parameters to use to access the database over JDBC
+     * @return the result of the operation
+     */
+    public ApexAPIResult loadFromDatabase(final String modelName, final String modelVersion,
+            final DAOParameters daoParameters) {
+        Assertions.argumentNotNull(modelName, "modelName may not be null");
+        Assertions.argumentNotNull(daoParameters, "daoParameters may not be null");
+
+        if (!apexModel.getPolicyModel().getKey().equals(AxArtifactKey.getNullKey())) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_EXISTS,
+                    MODEL + apexModel.getPolicyModel().getKey().getID() + ALREADY_LOADED);
+        }
+
+        ApexDao apexDao = null;
+        try {
+            apexDao = new ApexDaoFactory().createApexDao(daoParameters);
+            apexDao.init(daoParameters);
+
+            // Single specific model requested
+            if (modelVersion != null) {
+                AxPolicyModel daoPolicyModel =
+                        apexDao.get(AxPolicyModel.class, new AxArtifactKey(modelName, modelVersion));
+
+                if (daoPolicyModel != null) {
+                    apexModel.setPolicyModel(daoPolicyModel);
+                    return new ApexAPIResult();
+                } else {
+                    apexModel.setPolicyModel(new AxPolicyModel());
+                    return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, "no policy model with name " + modelName
+                            + " and version " + modelVersion + FOUND_IN_DATABASE);
+                }
+            }
+            // Fishing expedition
+            else {
+                return searchInDatabase(modelName, apexDao, apexModel);
+            }
+        } catch (ApexException | ApexRuntimeException e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        } finally {
+            if (apexDao != null) {
+                apexDao.close();
+            }
+        }
+    }
+
+    /**
+     * Search for an Apex model in the database.
+     *
+     * @param modelName the name of the model to load
+     * @param apexDao the DAO to use to find the model
+     * @param apexModel the APEX model we are loading the found model into
+     * @return the result of the operation
+     */
+    private ApexAPIResult searchInDatabase(String modelName, ApexDao apexDao, ApexModel apexModel) {
+        AxPolicyModel foundPolicyModel = null;
+
+        List<AxPolicyModel> policyModelList = apexDao.getAll(AxPolicyModel.class);
+        for (AxPolicyModel dbPolicyModel : policyModelList) {
+            if (dbPolicyModel.getKey().getName().equals(modelName)) {
+                if (foundPolicyModel == null) {
+                    foundPolicyModel = dbPolicyModel;
+                } else {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.FAILED,
+                            "more than one policy model with name " + modelName + FOUND_IN_DATABASE);
+                }
+            }
+        }
+
+        if (foundPolicyModel != null) {
+            apexModel.setPolicyModel(foundPolicyModel);
+            return new ApexAPIResult();
+        } else {
+            apexModel.setPolicyModel(new AxPolicyModel());
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED,
+                    "no policy model with name " + modelName + FOUND_IN_DATABASE);
+        }
+    }
+
+    /**
+     * Save an Apex model to a database.
+     *
+     * @param daoParameters the parameters to use to access the database over JDBC
+     * @return the result of the operation
+     */
+    public ApexAPIResult saveToDatabase(final DAOParameters daoParameters) {
+        ApexDao apexDao = null;
+
+        try {
+            apexDao = new ApexDaoFactory().createApexDao(daoParameters);
+            apexDao.init(daoParameters);
+
+            apexDao.create(apexModel.getPolicyModel());
+            return new ApexAPIResult();
+        } catch (ApexException e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        } finally {
+            if (apexDao != null) {
+                apexDao.close();
+            }
+        }
+    }
+
+    /**
+     * Read an APEX model from a location identified by a URL.
+     *
+     * @param urlString the url string
+     * @return the result of the operation
+     */
+    public ApexAPIResult readFromURL(final String urlString) {
+        Assertions.argumentNotNull(urlString, "urlString may not be null");
+
+        if (!apexModel.getPolicyModel().getKey().equals(AxArtifactKey.getNullKey())) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_EXISTS,
+                    MODEL + apexModel.getPolicyModel().getKey().getID() + ALREADY_LOADED);
+        }
+
+        URL apexModelURL;
+        try {
+            apexModelURL = new URL(urlString);
+        } catch (MalformedURLException e) {
+            ApexAPIResult result = new ApexAPIResult(ApexAPIResult.RESULT.FAILED);
+            result.addMessage("URL string " + urlString + " is not a valid URL");
+            result.addThrowable(e);
+            return result;
+        }
+
+        try {
+            ApexModelReader<AxPolicyModel> apexModelReader = new ApexModelReader<>(AxPolicyModel.class);
+            apexModelReader.setValidateFlag(false);
+            AxPolicyModel newPolicyModel = apexModelReader.read(apexModelURL.openStream());
+            apexModel.setPolicyModel(newPolicyModel != null ? newPolicyModel : new AxPolicyModel());
+            return new ApexAPIResult();
+        } catch (ApexModelException | IOException e) {
+            apexModel.setPolicyModel(new AxPolicyModel());
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Write an APEX model to a location identified by a URL.
+     *
+     * @param urlString the URL to read the model from
+     * @param xmlFlag if true, save the file in XML format, otherwise save the file in the default
+     *        JSON format
+     * @return the result of the operation
+     */
+    public ApexAPIResult writeToURL(final String urlString, final boolean xmlFlag) {
+        Assertions.argumentNotNull(urlString, "urlString may not be null");
+
+        URL apexModelURL;
+        try {
+            apexModelURL = new URL(urlString);
+        } catch (MalformedURLException e) {
+            ApexAPIResult result = new ApexAPIResult(ApexAPIResult.RESULT.FAILED);
+            result.addMessage("URL string " + urlString + " is not a valid URL");
+            result.addThrowable(e);
+            return result;
+        }
+
+        try {
+            ApexModelWriter<AxPolicyModel> apexModelWriter = new ApexModelWriter<>(AxPolicyModel.class);
+            apexModelWriter.setValidateFlag(false);
+            apexModelWriter.setJsonOutput(!xmlFlag);
+
+            // Open the URL for output and write the model
+            URLConnection urlConnection = apexModelURL.openConnection();
+            urlConnection.setDoOutput(true);
+
+            apexModelWriter.write(apexModel.getPolicyModel(), urlConnection.getOutputStream());
+            return new ApexAPIResult();
+        } catch (ApexModelException | IOException e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Analyse an Apex model that shows the concept usage references of a policy model.
+     *
+     * @return the result of the operation
+     */
+    public ApexAPIResult analyse() {
+        PolicyAnalysisResult analysisResult = new PolicyAnalyser().analyse(apexModel.getPolicyModel());
+        return new ApexAPIResult(ApexAPIResult.RESULT.SUCCESS, analysisResult.toString());
+    }
+
+    /**
+     * Validate an Apex model, checking all concepts and references in the model.
+     *
+     * @return the result of the operation
+     */
+    public ApexAPIResult validate() {
+        ApexAPIResult result = new ApexAPIResult();
+        try {
+            AxValidationResult validationResult = apexModel.getPolicyModel().validate(new AxValidationResult());
+
+            if (!validationResult.isValid()) {
+                result.setResult(ApexAPIResult.RESULT.FAILED);
+            }
+            result.addMessage(new ApexModelStringWriter<AxArtifactKey>(false)
+                    .writeString(apexModel.getPolicyModel().getKey(), AxArtifactKey.class, jsonMode));
+            result.addMessage(validationResult.toString());
+            return result;
+        } catch (Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Compare to Apex models, returning the differences between the models.
+     *
+     * @param otherModelFileName the file name of the other model
+     * @param diffsOnly only returns differences between the model when set
+     * @param keysOnly only returns the keys that are different when set, when not set values are
+     *        also returned
+     * @return the result of the operation
+     */
+    public ApexAPIResult compare(final String otherModelFileName, final boolean diffsOnly, final boolean keysOnly) {
+        ApexAPIResult result = new ApexAPIResult();
+        try {
+            AxPolicyModel otherPolicyModel = loadModelFromFile(otherModelFileName, result);
+            if (!result.getResult().equals(ApexAPIResult.RESULT.SUCCESS)) {
+                return result;
+            }
+
+            PolicyModelComparer policyModelComparer =
+                    new PolicyModelComparer(apexModel.getPolicyModel(), otherPolicyModel);
+            result.addMessage(new ApexModelStringWriter<AxArtifactKey>(false)
+                    .writeString(apexModel.getPolicyModel().getKey(), AxArtifactKey.class, jsonMode));
+            result.addMessage(policyModelComparer.toString());
+
+            return result;
+        } catch (Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Compare two Apex models, returning the differences between the models.
+     *
+     * @param otherModelString the other model as a string
+     * @param diffsOnly only returns differences between the model when set
+     * @param keysOnly only returns the keys that are different when set, when not set values are
+     *        also returned
+     * @return the result of the operation
+     */
+    public ApexAPIResult compareWithString(final String otherModelString, final boolean diffsOnly,
+            final boolean keysOnly) {
+        ApexAPIResult result = new ApexAPIResult();
+        try {
+            AxPolicyModel otherPolicyModel = loadModelFromString(otherModelString, result);
+            if (!result.getResult().equals(ApexAPIResult.RESULT.SUCCESS)) {
+                return result;
+            }
+
+            PolicyModelComparer policyModelComparer =
+                    new PolicyModelComparer(apexModel.getPolicyModel(), otherPolicyModel);
+            result.addMessage(new ApexModelStringWriter<AxArtifactKey>(false)
+                    .writeString(apexModel.getPolicyModel().getKey(), AxArtifactKey.class, jsonMode));
+            result.addMessage(policyModelComparer.toString());
+
+            return result;
+        } catch (Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Split out a sub model from an Apex model that contains a given subset of the policies in the
+     * original model.
+     *
+     * @param targetModelName the file name of the target model in which to store the model split
+     *        out from the original model
+     * @param splitOutPolicies the policies form the original model to include in the split out
+     *        model, specified as a comma delimited list of policy names
+     * @return the result of the operation
+     */
+    public ApexAPIResult split(final String targetModelName, final String splitOutPolicies) {
+        Set<AxArtifactKey> requiredPolicySet = new LinkedHashSet<>();
+
+        // Split the policy names on comma
+        String[] policyNames = splitOutPolicies.split(",");
+
+        // Iterate over the policy names
+        for (String policyName : policyNames) {
+            // Split out this specific policy
+            AxPolicy requiredPolicy = apexModel.getPolicyModel().getPolicies().get(policyName);
+
+            if (requiredPolicy != null) {
+                requiredPolicySet.add(requiredPolicy.getKey());
+            } else {
+                return new ApexAPIResult(ApexAPIResult.RESULT.FAILED,
+                        "policy for policy name " + policyName + " not found in model");
+            }
+        }
+
+        try {
+            AxPolicyModel splitPolicyModel =
+                    PolicyModelSplitter.getSubPolicyModel(apexModel.getPolicyModel(), requiredPolicySet, false);
+
+            ApexModelFileWriter<AxPolicyModel> apexModelFileWriter = new ApexModelFileWriter<>(false);
+            apexModelFileWriter.apexModelWriteJSONFile(splitPolicyModel, AxPolicyModel.class, targetModelName);
+            return new ApexAPIResult();
+        } catch (ApexException e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Split out a sub model from an Apex model that contains a given subset of the policies in the
+     * original model, return the split model in the result as a string.
+     *
+     * @param splitOutPolicies the policies form the original model to include in the split out
+     *        model, specified as a comma delimited list of policy names
+     * @return the result of the operation
+     */
+    public ApexAPIResult split(final String splitOutPolicies) {
+        ApexAPIResult splitResult = new ApexAPIResult();
+        File tempSplitPolicyFile = null;
+        try {
+            tempSplitPolicyFile = File.createTempFile("ApexTempPolicy", null);
+
+            // Split the policy into a temporary file
+            splitResult = split(tempSplitPolicyFile.getCanonicalPath(), splitOutPolicies);
+            if (splitResult.isNOK()) {
+                return splitResult;
+            }
+
+            // Get the policy model into a string
+            String splitPolicyModelString = TextFileUtils.getTextFileAsString(tempSplitPolicyFile.getCanonicalPath());
+
+            // Return the policy model
+            splitResult.addMessage(splitPolicyModelString);
+            return splitResult;
+        } catch (Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED,
+                    "split of policy model " + apexModel.getPolicyModel().getID() + " failed", e);
+        } finally {
+            if (tempSplitPolicyFile != null) {
+                try {
+                    Files.delete(tempSplitPolicyFile.toPath());
+                } catch (IOException e) {
+                    LOGGER.debug("delete of temporary file failed", e);
+                }
+            }
+        }
+    }
+
+    /**
+     * Merge two Apex models together.
+     *
+     * @param mergeInModelName the file name of the model to merge into the current model
+     * @param keepOriginal if this flag is set to true, if a concept exists in both models, the
+     *        original model copy of that concept is kept, if the flag is set to false, then the
+     *        copy of the concept from the mergeInModel overwrites the concept in the original model
+     * @return the result of the operation
+     */
+    public ApexAPIResult merge(final String mergeInModelName, final boolean keepOriginal) {
+        ApexAPIResult result = new ApexAPIResult();
+        AxPolicyModel mergeInPolicyModel = loadModelFromFile(mergeInModelName, result);
+        if (!result.getResult().equals(ApexAPIResult.RESULT.SUCCESS)) {
+            return result;
+        }
+
+        try {
+            AxPolicyModel mergedPolicyModel = PolicyModelMerger.getMergedPolicyModel(apexModel.getPolicyModel(),
+                    mergeInPolicyModel, keepOriginal, false);
+            apexModel.setPolicyModel(mergedPolicyModel != null ? mergedPolicyModel : new AxPolicyModel());
+            return new ApexAPIResult();
+        } catch (ApexModelException e) {
+            apexModel.setPolicyModel(new AxPolicyModel());
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Merge two Apex models together.
+     *
+     * @param otherModelString the model to merge as a string
+     * @param keepOriginal if this flag is set to true, if a concept exists in both models, the
+     *        original model copy of that concept is kept, if the flag is set to false, then the
+     *        copy of the concept from the mergeInModel overwrites the concept in the original model
+     * @return the result of the operation
+     */
+    public ApexAPIResult mergeWithString(final String otherModelString, final boolean keepOriginal) {
+        ApexAPIResult result = new ApexAPIResult();
+        AxPolicyModel mergeInPolicyModel = loadModelFromString(otherModelString, result);
+        if (!result.getResult().equals(ApexAPIResult.RESULT.SUCCESS)) {
+            return result;
+        }
+
+        try {
+            AxPolicyModel mergedPolicyModel = PolicyModelMerger.getMergedPolicyModel(apexModel.getPolicyModel(),
+                    mergeInPolicyModel, keepOriginal, false);
+            apexModel.setPolicyModel(mergedPolicyModel != null ? mergedPolicyModel : new AxPolicyModel());
+            return new ApexAPIResult();
+        } catch (ApexModelException e) {
+            apexModel.setPolicyModel(new AxPolicyModel());
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Load a policy model from a file.
+     *
+     * @param fileName the name of the file containing the model
+     * @param result the result of the operation
+     * @return the model
+     */
+    private AxPolicyModel loadModelFromFile(final String fileName, final ApexAPIResult result) {
+        Assertions.argumentNotNull(fileName, FILE_NAME_MAY_NOT_BE_NULL);
+
+        AxPolicyModel readModel = null;
+
+        final URL apexModelURL = ResourceUtils.getLocalFile(fileName);
+        if (apexModelURL == null) {
+            result.setResult(ApexAPIResult.RESULT.FAILED);
+            result.addMessage("file " + fileName + " not found");
+            return null;
+        }
+
+        try {
+            ApexModelReader<AxPolicyModel> apexModelReader = new ApexModelReader<>(AxPolicyModel.class);
+            apexModelReader.setValidateFlag(false);
+            readModel = apexModelReader.read(apexModelURL.openStream());
+            result.setResult(ApexAPIResult.RESULT.SUCCESS);
+            return readModel;
+        } catch (Exception e) {
+            result.setResult(ApexAPIResult.RESULT.FAILED);
+            result.addThrowable(e);
+            return null;
+        }
+    }
+
+    /**
+     * Load a policy model from a string.
+     *
+     * @param modelString the string containing the model
+     * @param result the result of the operation
+     * @return the model
+     */
+    private AxPolicyModel loadModelFromString(final String modelString, final ApexAPIResult result) {
+        Assertions.argumentNotNull(modelString, "modelString may not be null");
+
+        AxPolicyModel readModel = null;
+
+        InputStream modelStringStream = new ByteArrayInputStream(modelString.getBytes());
+
+        try {
+            ApexModelReader<AxPolicyModel> apexModelReader = new ApexModelReader<>(AxPolicyModel.class);
+            apexModelReader.setValidateFlag(false);
+            readModel = apexModelReader.read(modelStringStream);
+            result.setResult(ApexAPIResult.RESULT.SUCCESS);
+            return readModel;
+        } catch (Exception e) {
+            result.setResult(ApexAPIResult.RESULT.FAILED);
+            result.addThrowable(e);
+            return null;
+        }
+    }
+}
diff --git a/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/impl/PolicyFacade.java b/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/impl/PolicyFacade.java
new file mode 100644
index 0000000..f33627e
--- /dev/null
+++ b/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/impl/PolicyFacade.java
@@ -0,0 +1,1383 @@
+/*-
+ * ============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.model.modelapi.impl;
+
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeSet;
+
+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.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelStringWriter;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum;
+import org.onap.policy.apex.model.eventmodel.concepts.AxEvent;
+import org.onap.policy.apex.model.modelapi.ApexAPIResult;
+import org.onap.policy.apex.model.modelapi.ApexModel;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicy;
+import org.onap.policy.apex.model.policymodel.concepts.AxState;
+import org.onap.policy.apex.model.policymodel.concepts.AxStateFinalizerLogic;
+import org.onap.policy.apex.model.policymodel.concepts.AxStateOutput;
+import org.onap.policy.apex.model.policymodel.concepts.AxStateTaskOutputType;
+import org.onap.policy.apex.model.policymodel.concepts.AxStateTaskReference;
+import org.onap.policy.apex.model.policymodel.concepts.AxTask;
+import org.onap.policy.apex.model.policymodel.concepts.AxTaskSelectionLogic;
+import org.onap.policy.apex.model.utilities.Assertions;
+
+/**
+ * This class acts as a facade for operations towards a policy model for policy operations.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class PolicyFacade {
+    private static final String STATE_NAME_MAY_NOT_BE_NULL = "stateName may not be null";
+    private static final String DOES_NOT_EXIST_ON_STATE = " does not exist on state ";
+    private static final String STATE_FINALIZER_LOGIC = "state finalizer logic ";
+    private static final String DO_ES_NOT_EXIST = " do(es) not exist";
+    private static final String CONCEPT_S = "concept(s) ";
+    private static final String DOES_NOT_EXIST = " does not exist";
+    private static final String CONCEPT = "concept ";
+    private static final String ALREADY_EXISTS = " already exists";
+
+    // Apex model we're working towards
+    private final ApexModel apexModel;
+
+    // Properties to use for the model
+    private final Properties apexProperties;
+
+    // Facade classes for working towards the real Apex model
+    private final KeyInformationFacade keyInformationFacade;
+
+    // JSON output on list/delete if set
+    private final boolean jsonMode;
+
+    /**
+     * Constructor that creates a policy facade for the Apex Model API.
+     *
+     * @param apexModel the apex model
+     * @param apexProperties Properties for the model
+     * @param jsonMode set to true to return JSON strings in list and delete operations, otherwise
+     *        set to false
+     */
+    public PolicyFacade(final ApexModel apexModel, final Properties apexProperties, final boolean jsonMode) {
+        this.apexModel = apexModel;
+        this.apexProperties = apexProperties;
+        this.jsonMode = jsonMode;
+
+        keyInformationFacade = new KeyInformationFacade(apexModel, apexProperties, jsonMode);
+    }
+
+    /**
+     * Create a policy.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the default version
+     * @param template template used to create the policy, set to null to use the default template
+     * @param firstState the first state of the policy
+     * @param uuid policy UUID, set to null to generate a UUID
+     * @param description policy description, set to null to generate a description
+     * @return result of the operation
+     */
+    public ApexAPIResult createPolicy(final String name, final String version, final String template,
+            final String firstState, final String uuid, final String description) {
+        try {
+            final AxArtifactKey key = new AxArtifactKey();
+            key.setName(name);
+            if (version != null) {
+                key.setVersion(version);
+            } else {
+                key.setVersion(apexProperties.getProperty("DEFAULT_CONCEPT_VERSION"));
+            }
+
+            String t = template;
+            if (t == null) {
+                t = apexProperties.getProperty("DEFAULT_POLICY_TEMPLATE");
+            }
+
+            if (apexModel.getPolicyModel().getPolicies().getPolicyMap().containsKey(key)) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_EXISTS, CONCEPT + key.getID() + ALREADY_EXISTS);
+            }
+
+            final AxPolicy policy = new AxPolicy(key);
+            policy.setTemplate(t);
+            policy.setFirstState(firstState);
+
+            apexModel.getPolicyModel().getPolicies().getPolicyMap().put(key, policy);
+
+            if (apexModel.getPolicyModel().getKeyInformation().getKeyInfoMap().containsKey(key)) {
+                return keyInformationFacade.updateKeyInformation(name, version, uuid, description);
+            } else {
+                return keyInformationFacade.createKeyInformation(name, version, uuid, description);
+            }
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Update a policy.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param template template used to create the policy, set to null to not update
+     * @param firstState the first state of the policy
+     * @param uuid policy UUID, set to null to not update
+     * @param description policy description, set to null to not update
+     * @return result of the operation
+     */
+    public ApexAPIResult updatePolicy(final String name, final String version, final String template,
+            final String firstState, final String uuid, final String description) {
+        try {
+            final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+            if (policy == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            if (template != null) {
+                policy.setTemplate(template);
+            }
+            if (firstState != null) {
+                policy.setFirstState(firstState);
+            }
+
+            return keyInformationFacade.updateKeyInformation(name, version, uuid, description);
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * List policies.
+     *
+     * @param name name of the policy, set to null to list all
+     * @param version starting version of the policy, set to null to list all versions
+     * @return result of the operation
+     */
+    public ApexAPIResult listPolicy(final String name, final String version) {
+        try {
+            final Set<AxPolicy> policySet = apexModel.getPolicyModel().getPolicies().getAll(name, version);
+            if (name != null && policySet.isEmpty()) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
+            }
+
+            final ApexAPIResult result = new ApexAPIResult();
+            for (final AxPolicy policy : policySet) {
+                result.addMessage(
+                        new ApexModelStringWriter<AxPolicy>(false).writeString(policy, AxPolicy.class, jsonMode));
+            }
+            return result;
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Delete a policy.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @return result of the operation
+     */
+    public ApexAPIResult deletePolicy(final String name, final String version) {
+        try {
+            if (version != null) {
+                final AxArtifactKey key = new AxArtifactKey(name, version);
+                final AxPolicy removedPolicy = apexModel.getPolicyModel().getPolicies().getPolicyMap().remove(key);
+                if (removedPolicy != null) {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.SUCCESS, new ApexModelStringWriter<AxPolicy>(false)
+                            .writeString(removedPolicy, AxPolicy.class, jsonMode));
+                } else {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            CONCEPT + key.getID() + DOES_NOT_EXIST);
+                }
+            }
+
+            final Set<AxPolicy> policySet = apexModel.getPolicyModel().getPolicies().getAll(name, version);
+            if (policySet.isEmpty()) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
+            }
+
+            final ApexAPIResult result = new ApexAPIResult();
+            for (final AxPolicy policy : policySet) {
+                result.addMessage(
+                        new ApexModelStringWriter<AxPolicy>(false).writeString(policy, AxPolicy.class, jsonMode));
+                apexModel.getPolicyModel().getPolicies().getPolicyMap().remove(policy.getKey());
+                keyInformationFacade.deleteKeyInformation(name, version);
+            }
+            return result;
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Validate policies.
+     *
+     * @param name name of the policy, set to null to list all
+     * @param version starting version of the policy, set to null to list all versions
+     * @return result of the operation
+     */
+    public ApexAPIResult validatePolicy(final String name, final String version) {
+        try {
+            final Set<AxPolicy> policySet = apexModel.getPolicyModel().getPolicies().getAll(name, version);
+            if (policySet.isEmpty()) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
+            }
+
+            final ApexAPIResult result = new ApexAPIResult();
+            for (final AxPolicy policy : policySet) {
+                final AxValidationResult validationResult = policy.validate(new AxValidationResult());
+                result.addMessage(new ApexModelStringWriter<AxArtifactKey>(false).writeString(policy.getKey(),
+                        AxArtifactKey.class, jsonMode));
+                result.addMessage(validationResult.toString());
+            }
+            return result;
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Create a policy state.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state
+     * @param triggerName name of the trigger event for this state
+     * @param triggerVersion version of the trigger event for this state, set to null to use the
+     *        latest version
+     * @param defaultTaskName the default task name
+     * @param defaltTaskVersion the default task version, set to null to use the latest version
+     * @return result of the operation
+     */
+    public ApexAPIResult createPolicyState(final String name, final String version, final String stateName,
+            final String triggerName, final String triggerVersion, final String defaultTaskName,
+            final String defaltTaskVersion) {
+        try {
+            Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+
+            final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+            if (policy == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            final AxReferenceKey refKey = new AxReferenceKey(policy.getKey(), stateName);
+
+            if (policy.getStateMap().containsKey(refKey.getLocalName())) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_EXISTS,
+                        CONCEPT + refKey.getID() + ALREADY_EXISTS);
+            }
+
+            final AxEvent triggerEvent = apexModel.getPolicyModel().getEvents().get(triggerName, triggerVersion);
+            if (triggerEvent == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + triggerName + ':' + triggerVersion + DOES_NOT_EXIST);
+            }
+
+            final AxTask defaultTask = apexModel.getPolicyModel().getTasks().get(defaultTaskName, defaltTaskVersion);
+            if (defaultTask == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + defaultTaskName + ':' + defaltTaskVersion + DOES_NOT_EXIST);
+            }
+
+            final AxState state = new AxState(refKey);
+            state.setTrigger(triggerEvent.getKey());
+            state.setDefaultTask(defaultTask.getKey());
+
+            policy.getStateMap().put(state.getKey().getLocalName(), state);
+            return new ApexAPIResult();
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Update a policy state.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state
+     * @param triggerName name of the trigger event for this state, set to null to not update
+     * @param triggerVersion version of the trigger event for this state, set to use latest version
+     *        of trigger event
+     * @param defaultTaskName the default task name, set to null to not update
+     * @param defaltTaskVersion the default task version, set to use latest version of default task
+     * @return result of the operation
+     */
+    public ApexAPIResult updatePolicyState(final String name, final String version, final String stateName,
+            final String triggerName, final String triggerVersion, final String defaultTaskName,
+            final String defaltTaskVersion) {
+        try {
+            Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+
+            final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+            if (policy == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            final AxState state = policy.getStateMap().get(stateName);
+            if (state == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + policy.getKey().getID() + ':' + stateName + DOES_NOT_EXIST);
+            }
+
+            if (triggerName != null) {
+                final AxEvent triggerEvent = apexModel.getPolicyModel().getEvents().get(triggerName, triggerVersion);
+                if (triggerEvent == null) {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            CONCEPT + triggerName + ':' + triggerVersion + DOES_NOT_EXIST);
+                }
+                state.setTrigger(triggerEvent.getKey());
+            }
+
+            if (defaultTaskName != null) {
+                final AxTask defaultTask =
+                        apexModel.getPolicyModel().getTasks().get(defaultTaskName, defaltTaskVersion);
+                if (defaultTask == null) {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            CONCEPT + defaultTaskName + ':' + defaltTaskVersion + DOES_NOT_EXIST);
+                }
+                state.setDefaultTask(defaultTask.getKey());
+            }
+
+            return new ApexAPIResult();
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * List policy states.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state, set to null to list all states of the policy
+     * @return result of the operation
+     */
+    public ApexAPIResult listPolicyState(final String name, final String version, final String stateName) {
+        try {
+            final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+            if (policy == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            if (stateName != null) {
+                final AxState state = policy.getStateMap().get(stateName);
+                if (state != null) {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.SUCCESS,
+                            new ApexModelStringWriter<AxState>(false).writeString(state, AxState.class, jsonMode));
+                } else {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            CONCEPT + name + ':' + version + ':' + state + DOES_NOT_EXIST);
+                }
+            } else {
+                if (policy.getStateMap().size() == 0) {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            "no states defined on policy " + policy.getKey().getID());
+                }
+                final ApexAPIResult result = new ApexAPIResult();
+                for (final AxState state : policy.getStateMap().values()) {
+                    result.addMessage(
+                            new ApexModelStringWriter<AxState>(false).writeString(state, AxState.class, jsonMode));
+                }
+                return result;
+            }
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Delete a policy state.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state, set to null to delete all states
+     * @return result of the operation
+     */
+    public ApexAPIResult deletePolicyState(final String name, final String version, final String stateName) {
+        try {
+            final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+            if (policy == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            final ApexAPIResult result = new ApexAPIResult();
+            if (stateName != null) {
+                if (policy.getStateMap().containsKey(stateName)) {
+                    result.addMessage(new ApexModelStringWriter<AxState>(false)
+                            .writeString(policy.getStateMap().get(stateName), AxState.class, jsonMode));
+                    policy.getStateMap().remove(stateName);
+                    return result;
+                } else {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            CONCEPT + name + ':' + version + ':' + stateName + DOES_NOT_EXIST);
+                }
+            } else {
+                if (policy.getStateMap().size() == 0) {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            "no states defined on policy " + policy.getKey().getID());
+                }
+                for (final AxState state : policy.getStateMap().values()) {
+                    result.addMessage(
+                            new ApexModelStringWriter<AxState>(false).writeString(state, AxState.class, jsonMode));
+                }
+                policy.getStateMap().clear();
+                return result;
+            }
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Create task selection logic for a state.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state
+     * @param logicFlavour the task selection logic flavour for the state, set to null to use the
+     *        default task logic flavour
+     * @param logic the source code for the logic of the state
+     * @return result of the operation
+     */
+    public ApexAPIResult createPolicyStateTaskSelectionLogic(final String name, final String version,
+            final String stateName, final String logicFlavour, final String logic) {
+        try {
+            Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+
+            final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+            if (policy == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            final AxState state = policy.getStateMap().get(stateName);
+            if (state == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + policy.getKey().getID() + ':' + stateName + DOES_NOT_EXIST);
+            }
+
+            // There is only one logic item associated with a state so we use a hard coded logic
+            // name
+            final AxReferenceKey refKey = new AxReferenceKey(state.getKey(), "TaskSelectionLogic");
+
+            if (!state.getTaskSelectionLogic().getKey().getLocalName().equals(AxKey.NULL_KEY_NAME)) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_EXISTS,
+                        CONCEPT + refKey.getID() + ALREADY_EXISTS);
+            }
+
+            state.setTaskSelectionLogic(new AxTaskSelectionLogic(refKey, logicFlavour, logic));
+            return new ApexAPIResult();
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Update task selection logic for a state.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state
+     * @param logicFlavour the task selection logic flavour for the state, set to null to not update
+     * @param logic the source code for the logic of the state, set to null to not update
+     * @return result of the operation
+     */
+    public ApexAPIResult updatePolicyStateTaskSelectionLogic(final String name, final String version,
+            final String stateName, final String logicFlavour, final String logic) {
+        try {
+            Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+
+            final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+            if (policy == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            final AxState state = policy.getStateMap().get(stateName);
+            if (state == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + policy.getKey().getID() + ':' + stateName + DOES_NOT_EXIST);
+            }
+
+            if (state.getTaskSelectionLogic().getKey().getLocalName().equals(AxKey.NULL_KEY_NAME)) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + state.getTaskSelectionLogic().getKey().getID() + DOES_NOT_EXIST);
+            }
+
+            final AxTaskSelectionLogic taskSelectionLogic = state.getTaskSelectionLogic();
+            if (logicFlavour != null) {
+                taskSelectionLogic.setLogicFlavour(logicFlavour);
+            }
+            if (logic != null) {
+                taskSelectionLogic.setLogic(logic);
+            }
+
+            return new ApexAPIResult();
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * List task selection logic for a state.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state
+     * @return result of the operation
+     */
+    public ApexAPIResult listPolicyStateTaskSelectionLogic(final String name, final String version,
+            final String stateName) {
+        try {
+            Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+
+            final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+            if (policy == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            final AxState state = policy.getStateMap().get(stateName);
+            if (state == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + policy.getKey().getID() + ':' + stateName + DOES_NOT_EXIST);
+            }
+
+            return new ApexAPIResult(ApexAPIResult.RESULT.SUCCESS,
+                    new ApexModelStringWriter<AxTaskSelectionLogic>(false).writeString(state.getTaskSelectionLogic(),
+                            AxTaskSelectionLogic.class, jsonMode));
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Delete task selection logic for a state.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state
+     * @return result of the operation
+     */
+    public ApexAPIResult deletePolicyStateTaskSelectionLogic(final String name, final String version,
+            final String stateName) {
+        try {
+            Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+
+            final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+            if (policy == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            final AxState state = policy.getStateMap().get(stateName);
+            if (state == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + policy.getKey().getID() + ':' + stateName + DOES_NOT_EXIST);
+            }
+
+            if (state.getTaskSelectionLogic().getKey().getLocalName().equals(AxKey.NULL_KEY_NAME)) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + state.getTaskSelectionLogic().getKey().getID() + DOES_NOT_EXIST);
+            }
+
+            final ApexAPIResult result = new ApexAPIResult();
+            result.addMessage(new ApexModelStringWriter<AxTaskSelectionLogic>(false)
+                    .writeString(state.getTaskSelectionLogic(), AxTaskSelectionLogic.class, jsonMode));
+            state.setTaskSelectionLogic(new AxTaskSelectionLogic());
+            return result;
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Create a policy state output.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state
+     * @param outputName of the state output
+     * @param eventName name of the output event for this state output
+     * @param eventVersion version of the output event for this state output, set to null to use the
+     *        latest version
+     * @param nextState for this state to transition to, set to null if this is the last state that
+     *        the policy transitions to on this branch
+     * @return result of the operation
+     */
+    public ApexAPIResult createPolicyStateOutput(final String name, final String version, final String stateName,
+            final String outputName, final String eventName, final String eventVersion, final String nextState) {
+        try {
+            Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+            Assertions.argumentNotNull(outputName, "outputName may not be null");
+
+            final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+            if (policy == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        "Policy concept " + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            final AxState state = policy.getStateMap().get(stateName);
+            if (state == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        "State concept " + policy.getKey().getID() + ':' + stateName + DOES_NOT_EXIST);
+            }
+
+            final AxReferenceKey refKey = new AxReferenceKey(state.getKey(), outputName);
+            if (state.getStateOutputs().containsKey(refKey.getLocalName())) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_EXISTS,
+                        "Output concept " + refKey.getID() + ALREADY_EXISTS);
+            }
+
+            final AxEvent event = apexModel.getPolicyModel().getEvents().get(eventName, eventVersion);
+            if (event == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        "Event concept " + eventName + ':' + eventVersion + DOES_NOT_EXIST);
+            }
+
+            AxReferenceKey nextStateKey = AxReferenceKey.getNullKey();
+            if (nextState != null && !(AxReferenceKey.getNullKey().getLocalName().equals(nextState))) {
+                if (state.getKey().getLocalName().equals(nextState)) {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.FAILED,
+                            "next state " + nextState + " of a state cannot be the state itself");
+                }
+                nextStateKey = new AxReferenceKey(state.getKey().getParentArtifactKey(), nextState);
+
+                if (!policy.getStateMap().containsKey(nextState)) {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            "Next state concept " + nextStateKey.getID() + DOES_NOT_EXIST);
+                }
+            }
+
+            state.getStateOutputs().put(refKey.getLocalName(), new AxStateOutput(refKey, event.getKey(), nextStateKey));
+            return new ApexAPIResult();
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * List policy state outputs.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state
+     * @param outputName of the state output, set to null to list all outputs of the state
+     * @return result of the operation
+     */
+    public ApexAPIResult listPolicyStateOutput(final String name, final String version, final String stateName,
+            final String outputName) {
+        try {
+            Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+
+            final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+            if (policy == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            final AxState state = policy.getStateMap().get(stateName);
+            if (state == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + policy.getKey().getID() + ':' + stateName + DOES_NOT_EXIST);
+            }
+
+            if (outputName != null) {
+                final AxStateOutput stateOutput = state.getStateOutputs().get(outputName);
+                if (stateOutput != null) {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.SUCCESS,
+                            new ApexModelStringWriter<AxStateOutput>(false).writeString(stateOutput,
+                                    AxStateOutput.class, jsonMode));
+                } else {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            CONCEPT + state.getKey().getID() + ':' + outputName + DOES_NOT_EXIST);
+                }
+            } else {
+                if (state.getStateOutputs().size() == 0) {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            "no state output concepts exist for state " + state.getKey().getID());
+                }
+
+                final ApexAPIResult result = new ApexAPIResult();
+
+                for (final AxStateOutput stateOutput : state.getStateOutputs().values()) {
+                    result.addMessage(new ApexModelStringWriter<AxStateOutput>(false).writeString(stateOutput,
+                            AxStateOutput.class, jsonMode));
+                }
+                return result;
+            }
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Delete a policy state output.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state
+     * @param outputName of the state output, set to null to delete all state outputs
+     * @return result of the operation
+     */
+    public ApexAPIResult deletePolicyStateOutput(final String name, final String version, final String stateName,
+            final String outputName) {
+        try {
+            Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+
+            final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+            if (policy == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            final AxState state = policy.getStateMap().get(stateName);
+            if (state == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + policy.getKey().getID() + ':' + stateName + DOES_NOT_EXIST);
+            }
+
+            if (outputName != null) {
+                final AxStateOutput stateOutput = state.getStateOutputs().get(outputName);
+                if (stateOutput != null) {
+                    final ApexAPIResult result = new ApexAPIResult(ApexAPIResult.RESULT.SUCCESS,
+                            new ApexModelStringWriter<AxStateOutput>(false).writeString(stateOutput,
+                                    AxStateOutput.class, jsonMode));
+                    state.getStateOutputs().remove(outputName);
+                    return result;
+                } else {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            CONCEPT + state.getKey().getID() + ':' + outputName + DOES_NOT_EXIST);
+                }
+            } else {
+                if (state.getStateOutputs().size() == 0) {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            "no state output concepts exist for state " + state.getKey().getID());
+                }
+
+                final ApexAPIResult result = new ApexAPIResult();
+
+                for (final Entry<String, AxStateOutput> stateOutputEntry : state.getStateOutputs().entrySet()) {
+                    result.addMessage(new ApexModelStringWriter<AxStateOutput>(false)
+                            .writeString(stateOutputEntry.getValue(), AxStateOutput.class, jsonMode));
+                }
+                state.getStateOutputs().clear();
+                return result;
+            }
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Create policy finalizer logic for a state.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state
+     * @param finalizerLogicName name of the state finalizer logic
+     * @param logicFlavour the policy finalizer logic flavour for the state, set to null to use the
+     *        default task logic flavour
+     * @param logic the source code for the logic of the state
+     * @return result of the operation
+     */
+    public ApexAPIResult createPolicyStateFinalizerLogic(final String name, final String version,
+            final String stateName, final String finalizerLogicName, final String logicFlavour, final String logic) {
+        try {
+            Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+            Assertions.argumentNotNull(finalizerLogicName, "finalizerlogicName may not be null");
+
+            final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+            if (policy == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            final AxState state = policy.getStateMap().get(stateName);
+            if (state == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + policy.getKey().getID() + ':' + stateName + DOES_NOT_EXIST);
+            }
+
+            final AxReferenceKey refKey = new AxReferenceKey(state.getKey(), finalizerLogicName);
+
+            if (state.getStateFinalizerLogicMap().containsKey(refKey.getLocalName())) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_EXISTS,
+                        CONCEPT + refKey.getID() + ALREADY_EXISTS);
+            }
+
+            state.getStateFinalizerLogicMap().put(finalizerLogicName,
+                    new AxStateFinalizerLogic(refKey, logicFlavour, logic));
+            return new ApexAPIResult();
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Update policy finalizer logic for a state.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state
+     * @param finalizerLogicName name of the state finalizer logic
+     * @param logicFlavour the policy finalizer logic flavour for the state, set to null to not
+     *        update
+     * @param logic the source code for the logic of the state, set to null to not update
+     * @return result of the operation
+     */
+    public ApexAPIResult updatePolicyStateFinalizerLogic(final String name, final String version,
+            final String stateName, final String finalizerLogicName, final String logicFlavour, final String logic) {
+        try {
+            Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+            Assertions.argumentNotNull(finalizerLogicName, "finalizerLogicName may not be null");
+
+            final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+            if (policy == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            final AxState state = policy.getStateMap().get(stateName);
+            if (state == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + policy.getKey().getID() + ':' + stateName + DOES_NOT_EXIST);
+            }
+
+            final AxReferenceKey refKey = new AxReferenceKey(state.getKey(), finalizerLogicName);
+            final AxStateFinalizerLogic stateFinalizerLogic =
+                    state.getStateFinalizerLogicMap().get(refKey.getKey().getLocalName());
+            if (stateFinalizerLogic == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        STATE_FINALIZER_LOGIC + refKey.getID() + DOES_NOT_EXIST);
+            }
+
+            if (logicFlavour != null) {
+                stateFinalizerLogic.setLogicFlavour(logicFlavour);
+            }
+            if (logic != null) {
+                stateFinalizerLogic.setLogic(logic);
+            }
+
+            return new ApexAPIResult();
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * List policy finalizer logic for a state.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state
+     * @param finalizerLogicName name of the state finalizer logic
+     * @return result of the operation
+     */
+    public ApexAPIResult listPolicyStateFinalizerLogic(final String name, final String version, final String stateName,
+            final String finalizerLogicName) {
+        try {
+            Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+
+            final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+            if (policy == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            final AxState state = policy.getStateMap().get(stateName);
+            if (state == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + policy.getKey().getID() + ':' + stateName + DOES_NOT_EXIST);
+            }
+
+            if (finalizerLogicName != null) {
+                final AxReferenceKey refKey = new AxReferenceKey(state.getKey(), finalizerLogicName);
+                final AxStateFinalizerLogic stateFinalizerLogic =
+                        state.getStateFinalizerLogicMap().get(refKey.getKey().getLocalName());
+                if (stateFinalizerLogic == null) {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            STATE_FINALIZER_LOGIC + refKey.getID() + DOES_NOT_EXIST);
+                }
+
+                return new ApexAPIResult(ApexAPIResult.RESULT.SUCCESS,
+                        new ApexModelStringWriter<AxStateFinalizerLogic>(false).writeString(stateFinalizerLogic,
+                                AxStateFinalizerLogic.class, jsonMode));
+            } else {
+                if (state.getStateFinalizerLogicMap().size() == 0) {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            "no state finalizer logic defined on state " + state.getKey().getID());
+                }
+                final ApexAPIResult result = new ApexAPIResult();
+                for (final AxStateFinalizerLogic stateFinalizerLogic : state.getStateFinalizerLogicMap().values()) {
+                    result.addMessage(new ApexModelStringWriter<AxStateFinalizerLogic>(false)
+                            .writeString(stateFinalizerLogic, AxStateFinalizerLogic.class, jsonMode));
+                }
+                return result;
+            }
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Delete policy finalizer logic for a state.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state
+     * @param finalizerLogicName name of the state finalizer logic
+     * @return result of the operation
+     */
+    public ApexAPIResult deletePolicyStateFinalizerLogic(final String name, final String version,
+            final String stateName, final String finalizerLogicName) {
+        try {
+            Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+
+            final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+            if (policy == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            final AxState state = policy.getStateMap().get(stateName);
+            if (state == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + policy.getKey().getID() + ':' + stateName + DOES_NOT_EXIST);
+            }
+
+            if (finalizerLogicName != null) {
+                final AxReferenceKey refKey = new AxReferenceKey(state.getKey(), finalizerLogicName);
+                final AxStateFinalizerLogic stateFinalizerLogic =
+                        state.getStateFinalizerLogicMap().get(refKey.getKey().getLocalName());
+                if (stateFinalizerLogic == null) {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            STATE_FINALIZER_LOGIC + refKey.getID() + DOES_NOT_EXIST);
+                }
+
+                final ApexAPIResult result = new ApexAPIResult();
+                result.addMessage(new ApexModelStringWriter<AxStateFinalizerLogic>(false)
+                        .writeString(stateFinalizerLogic, AxStateFinalizerLogic.class, jsonMode));
+                state.getStateFinalizerLogicMap().remove(refKey.getLocalName());
+                return result;
+            } else {
+                if (state.getStateFinalizerLogicMap().size() == 0) {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            "no state finalizer logic defined on state " + state.getKey().getID());
+                }
+
+                final ApexAPIResult result = new ApexAPIResult();
+                for (final AxStateFinalizerLogic stateFinalizerLogic : state.getStateFinalizerLogicMap().values()) {
+                    result.addMessage(new ApexModelStringWriter<AxStateFinalizerLogic>(false)
+                            .writeString(stateFinalizerLogic, AxStateFinalizerLogic.class, jsonMode));
+                }
+                state.getStateFinalizerLogicMap().clear();
+                return result;
+            }
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Create a policy state task reference.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state
+     * @param taskLocalName the task local name
+     * @param taskName name of the task
+     * @param taskVersion version of the task, set to null to use the latest version
+     * @param outputType Type of output for the task, must be DIRECT for direct output to a state
+     *        output or LOGIC for output to state finalizer logic
+     * @param outputName the name of the state output or state state finalizer logic to handle the
+     *        task output
+     * @return result of the operation
+     */
+    // CHECKSTYLE:OFF: checkstyle:parameterNumber
+    public ApexAPIResult createPolicyStateTaskRef(final String name, final String version, final String stateName,
+            final String taskLocalName, final String taskName, final String taskVersion, final String outputType,
+            final String outputName) {
+        try {
+            Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+            Assertions.argumentNotNull(outputName, "outputName may not be null");
+
+            final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+            if (policy == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            final AxState state = policy.getStateMap().get(stateName);
+            if (state == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + policy.getKey().getID() + ':' + stateName + DOES_NOT_EXIST);
+            }
+
+            final AxTask task = apexModel.getPolicyModel().getTasks().get(taskName, taskVersion);
+            if (task == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + taskName + ':' + taskVersion + DOES_NOT_EXIST);
+            }
+
+            if (state.getTaskReferences().containsKey(task.getKey())) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_EXISTS, "task " + task.getKey().getID()
+                        + " already has reference with output " + state.getTaskReferences().get(task.getKey()));
+            }
+
+            AxReferenceKey refKey;
+            if (taskLocalName == null) {
+                refKey = new AxReferenceKey(state.getKey(), state.getKey().getParentKeyName());
+            } else {
+                refKey = new AxReferenceKey(state.getKey(), taskLocalName);
+            }
+
+            // The reference to the output we're using here
+            final AxReferenceKey outputRefKey = new AxReferenceKey(state.getKey(), outputName);
+
+            final AxStateTaskOutputType stateTaskOutputType = AxStateTaskOutputType.valueOf(outputType);
+            if (stateTaskOutputType.equals(AxStateTaskOutputType.DIRECT)) {
+                if (!state.getStateOutputs().containsKey(outputRefKey.getLocalName())) {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            "state output concept " + outputRefKey.getID() + DOES_NOT_EXIST);
+                }
+            } else if (stateTaskOutputType.equals(AxStateTaskOutputType.LOGIC)) {
+                if (!state.getStateFinalizerLogicMap().containsKey(outputRefKey.getLocalName())) {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            "state finalizer logic concept " + outputRefKey.getID() + DOES_NOT_EXIST);
+                }
+            } else {
+                return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, "output type " + outputType + " invalid");
+            }
+
+            state.getTaskReferences().put(task.getKey(),
+                    new AxStateTaskReference(refKey, stateTaskOutputType, outputRefKey));
+            return new ApexAPIResult();
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+    // CHECKSTYLE:ON: checkstyle:parameterNumber
+
+    /**
+     * List policy state task references.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state
+     * @param taskName name of the task, set to null to list all task references
+     * @param taskVersion version of the task, set to null to use the latest version
+     * @return result of the operation
+     */
+    public ApexAPIResult listPolicyStateTaskRef(final String name, final String version, final String stateName,
+            final String taskName, final String taskVersion) {
+        try {
+            Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+
+            final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+            if (policy == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            final AxState state = policy.getStateMap().get(stateName);
+            if (state == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + policy.getKey().getID() + ':' + stateName + DOES_NOT_EXIST);
+            }
+
+            final ApexAPIResult result = new ApexAPIResult();
+            boolean found = false;
+            for (final Entry<AxArtifactKey, AxStateTaskReference> taskReferenceEntry : state.getTaskReferences()
+                    .entrySet()) {
+                if (taskName == null) {
+                    result.addMessage(new ApexModelStringWriter<AxArtifactKey>(false)
+                            .writeString(taskReferenceEntry.getKey(), AxArtifactKey.class, jsonMode));
+                    result.addMessage(new ApexModelStringWriter<AxStateTaskReference>(false)
+                            .writeString(taskReferenceEntry.getValue(), AxStateTaskReference.class, jsonMode));
+                    found = true;
+                    continue;
+                }
+                if (!taskReferenceEntry.getKey().getName().equals(taskName)) {
+                    continue;
+                }
+
+                if (taskVersion != null && !taskReferenceEntry.getKey().getVersion().equals(taskVersion)) {
+                    continue;
+                }
+
+                found = true;
+                result.addMessage(new ApexModelStringWriter<AxArtifactKey>(false)
+                        .writeString(taskReferenceEntry.getKey(), AxArtifactKey.class, jsonMode));
+                result.addMessage(new ApexModelStringWriter<AxStateTaskReference>(false)
+                        .writeString(taskReferenceEntry.getValue(), AxStateTaskReference.class, jsonMode));
+            }
+            if (found) {
+                return result;
+            } else {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        "no task references found for state " + state.getKey().getID());
+            }
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Delete a policy state task reference.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state
+     * @param taskName name of the task, set to null to delete all task references
+     * @param taskVersion version of the task, set to null to use the latest version
+     * @return result of the operation
+     */
+    public ApexAPIResult deletePolicyStateTaskRef(final String name, final String version, final String stateName,
+            final String taskName, final String taskVersion) {
+        try {
+            Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+
+            final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+            if (policy == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            final AxState state = policy.getStateMap().get(stateName);
+            if (state == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + policy.getKey().getID() + ':' + stateName + DOES_NOT_EXIST);
+            }
+
+            final Set<AxArtifactKey> deleteSet = new TreeSet<>();
+
+            for (final AxArtifactKey taskReferenceKey : state.getTaskReferences().keySet()) {
+                if (taskName == null) {
+                    deleteSet.add(taskReferenceKey);
+                    continue;
+                }
+                if (!taskReferenceKey.getName().equals(taskName)) {
+                    continue;
+                }
+
+                if (taskVersion != null && !taskReferenceKey.getVersion().equals(taskVersion)) {
+                    continue;
+                }
+                deleteSet.add(taskReferenceKey);
+            }
+            if (deleteSet.isEmpty()) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + taskName + ':' + taskVersion + DOES_NOT_EXIST_ON_STATE + state.getKey().getID());
+            }
+
+            final ApexAPIResult result = new ApexAPIResult();
+            for (final AxArtifactKey keyToDelete : deleteSet) {
+                state.getTaskReferences().remove(keyToDelete);
+                result.addMessage(new ApexModelStringWriter<AxArtifactKey>(false).writeString(keyToDelete,
+                        AxArtifactKey.class, jsonMode));
+            }
+            return result;
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Create a policy state context album reference.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state
+     * @param contextAlbumName name of the context album for the context album reference
+     * @param contextAlbumVersion version of the context album for the context album reference, set
+     *        to null to use the latest version
+     * @return result of the operation
+     */
+    public ApexAPIResult createPolicyStateContextRef(final String name, final String version, final String stateName,
+            final String contextAlbumName, final String contextAlbumVersion) {
+        try {
+            Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+
+            final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+            if (policy == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            final AxState state = policy.getStateMap().get(stateName);
+            if (state == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + policy.getKey().getID() + ':' + stateName + DOES_NOT_EXIST);
+            }
+
+            final AxContextAlbum contextAlbum =
+                    apexModel.getPolicyModel().getAlbums().get(contextAlbumName, contextAlbumVersion);
+            if (contextAlbum == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + contextAlbumName + ':' + contextAlbumVersion + DOES_NOT_EXIST);
+            }
+
+            if (state.getContextAlbumReferences().contains(contextAlbum.getKey())) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_EXISTS, "concept album reference for concept "
+                        + contextAlbum.getKey().getID() + " already exists in state");
+            }
+
+            state.getContextAlbumReferences().add(contextAlbum.getKey());
+            return new ApexAPIResult();
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * List policy state context album references.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the latest version
+     * @param stateName of the state
+     * @param contextAlbumName name of the context album for the context album reference, set to
+     *        null to list all task context album references
+     * @param contextAlbumVersion version of the context album for the context album reference, set
+     *        to null to use the latest version
+     * @return result of the operation
+     */
+    public ApexAPIResult listPolicyStateContextRef(final String name, final String version, final String stateName,
+            final String contextAlbumName, final String contextAlbumVersion) {
+        try {
+            Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+
+            final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+            if (policy == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            final AxState state = policy.getStateMap().get(stateName);
+            if (state == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + policy.getKey().getID() + ':' + stateName + DOES_NOT_EXIST);
+            }
+
+            final ApexAPIResult result = new ApexAPIResult();
+            boolean found = false;
+            for (final AxArtifactKey albumKey : state.getContextAlbumReferences()) {
+                if (contextAlbumName == null) {
+                    result.addMessage(new ApexModelStringWriter<AxArtifactKey>(false).writeString(albumKey,
+                            AxArtifactKey.class, jsonMode));
+                    found = true;
+                    continue;
+                }
+
+                if (!albumKey.getName().equals(contextAlbumName)) {
+                    continue;
+                }
+
+                if (contextAlbumVersion == null || albumKey.getVersion().equals(contextAlbumVersion)) {
+                    result.addMessage(new ApexModelStringWriter<AxArtifactKey>(false).writeString(albumKey,
+                            AxArtifactKey.class, jsonMode));
+                    found = true;
+                }
+            }
+            if (!found) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST, CONCEPT + contextAlbumName + ':'
+                        + contextAlbumVersion + DOES_NOT_EXIST_ON_STATE + state.getKey().getID());
+            }
+            return result;
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Delete a policy state context album reference.
+     *
+     * @param name name of the policy
+     * @param version version of the policy, set to null to use the default version
+     * @param stateName of the state
+     * @param contextAlbumName name of the context album for the context album reference, set to
+     *        null to delete all task context album references
+     * @param contextAlbumVersion version of the context album for the context album reference, set
+     *        to null to use the latest version
+     * @return result of the operation
+     */
+    public ApexAPIResult deletePolicyStateContextRef(final String name, final String version, final String stateName,
+            final String contextAlbumName, final String contextAlbumVersion) {
+        try {
+            Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
+
+            final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
+            if (policy == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            final AxState state = policy.getStateMap().get(stateName);
+            if (state == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + policy.getKey().getID() + ':' + stateName + DOES_NOT_EXIST);
+            }
+
+            final Set<AxArtifactKey> deleteSet = new TreeSet<>();
+
+            for (final AxArtifactKey albumKey : state.getContextAlbumReferences()) {
+                if (contextAlbumName == null) {
+                    deleteSet.add(albumKey);
+                    continue;
+                }
+
+                if (!albumKey.getName().equals(contextAlbumName)) {
+                    continue;
+                }
+
+                if (contextAlbumVersion == null || albumKey.getVersion().equals(contextAlbumVersion)) {
+                    deleteSet.add(albumKey);
+                }
+            }
+            if (deleteSet.isEmpty()) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST, CONCEPT + contextAlbumName + ':'
+                        + contextAlbumVersion + DOES_NOT_EXIST_ON_STATE + state.getKey().getID());
+            }
+
+            final ApexAPIResult result = new ApexAPIResult();
+            for (final AxArtifactKey keyToDelete : deleteSet) {
+                state.getContextAlbumReferences().remove(keyToDelete);
+                result.addMessage(new ApexModelStringWriter<AxArtifactKey>(false).writeString(keyToDelete,
+                        AxArtifactKey.class, jsonMode));
+            }
+            return result;
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+}
diff --git a/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/impl/TaskFacade.java b/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/impl/TaskFacade.java
new file mode 100644
index 0000000..923814d
--- /dev/null
+++ b/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/impl/TaskFacade.java
@@ -0,0 +1,893 @@
+/*-
+ * ============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.model.modelapi.impl;
+
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeSet;
+
+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.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelStringWriter;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+import org.onap.policy.apex.model.eventmodel.concepts.AxInputField;
+import org.onap.policy.apex.model.eventmodel.concepts.AxOutputField;
+import org.onap.policy.apex.model.modelapi.ApexAPIResult;
+import org.onap.policy.apex.model.modelapi.ApexModel;
+import org.onap.policy.apex.model.policymodel.concepts.AxTask;
+import org.onap.policy.apex.model.policymodel.concepts.AxTaskLogic;
+import org.onap.policy.apex.model.policymodel.concepts.AxTaskParameter;
+import org.onap.policy.apex.model.utilities.Assertions;
+
+/**
+ * This class acts as a facade for operations towards a policy model for task operations.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class TaskFacade {
+    private static final String CONCEPT = "concept ";
+    private static final String CONCEPT_S = "concept(s) ";
+    private static final String DOES_NOT_EXIST = " does not exist";
+    private static final String DO_ES_NOT_EXIST = " do(es) not exist";
+    private static final String ALREADY_EXISTS = " already exists";
+
+    // Apex model we're working towards
+    private final ApexModel apexModel;
+
+    // Properties to use for the model
+    private final Properties apexProperties;
+
+    // Facade classes for working towards the real Apex model
+    private final KeyInformationFacade keyInformationFacade;
+
+    // JSON output on list/delete if set
+    private final boolean jsonMode;
+
+    /**
+     * Constructor that creates a task facade for the Apex Model API.
+     *
+     * @param apexModel the apex model
+     * @param apexProperties Properties for the model
+     * @param jsonMode set to true to return JSON strings in list and delete operations, otherwise
+     *        set to false
+     */
+    public TaskFacade(final ApexModel apexModel, final Properties apexProperties, final boolean jsonMode) {
+        this.apexModel = apexModel;
+        this.apexProperties = apexProperties;
+        this.jsonMode = jsonMode;
+
+        keyInformationFacade = new KeyInformationFacade(apexModel, apexProperties, jsonMode);
+    }
+
+    /**
+     * Create a task.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to use the default version
+     * @param uuid task UUID, set to null to generate a UUID
+     * @param description task description, set to null to generate a description
+     * @return result of the operation
+     */
+    public ApexAPIResult createTask(final String name, final String version, final String uuid,
+            final String description) {
+        try {
+            final AxArtifactKey key = new AxArtifactKey();
+            key.setName(name);
+            if (version != null) {
+                key.setVersion(version);
+            } else {
+                key.setVersion(apexProperties.getProperty("DEFAULT_CONCEPT_VERSION"));
+            }
+
+            if (apexModel.getPolicyModel().getTasks().getTaskMap().containsKey(key)) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_EXISTS, CONCEPT + key.getID() + ALREADY_EXISTS);
+            }
+
+            apexModel.getPolicyModel().getTasks().getTaskMap().put(key, new AxTask(key));
+
+            if (apexModel.getPolicyModel().getKeyInformation().getKeyInfoMap().containsKey(key)) {
+                return keyInformationFacade.updateKeyInformation(name, version, uuid, description);
+            } else {
+                return keyInformationFacade.createKeyInformation(name, version, uuid, description);
+            }
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Update a task.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to use the latest version
+     * @param uuid task UUID, set to null to not update
+     * @param description task description, set to null to not update
+     * @return result of the operation
+     */
+    public ApexAPIResult updateTask(final String name, final String version, final String uuid,
+            final String description) {
+        try {
+            final AxTask task = apexModel.getPolicyModel().getTasks().get(name, version);
+            if (task == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            return keyInformationFacade.updateKeyInformation(name, version, uuid, description);
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * List tasks.
+     *
+     * @param name name of the task, set to null to list all
+     * @param version starting version of the task, set to null to list all versions
+     * @return result of the operation
+     */
+    public ApexAPIResult listTask(final String name, final String version) {
+        try {
+            final Set<AxTask> taskSet = apexModel.getPolicyModel().getTasks().getAll(name, version);
+            if (name != null && taskSet.isEmpty()) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
+            }
+
+            final ApexAPIResult result = new ApexAPIResult();
+            for (final AxTask task : taskSet) {
+                result.addMessage(new ApexModelStringWriter<AxTask>(false).writeString(task, AxTask.class, jsonMode));
+            }
+            return result;
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Delete a task.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to use the latest version
+     * @return result of the operation
+     */
+    public ApexAPIResult deleteTask(final String name, final String version) {
+        try {
+            if (version != null) {
+                final AxArtifactKey key = new AxArtifactKey(name, version);
+                final AxTask removedTask = apexModel.getPolicyModel().getTasks().getTaskMap().remove(key);
+                if (removedTask != null) {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.SUCCESS,
+                            new ApexModelStringWriter<AxTask>(false).writeString(removedTask, AxTask.class, jsonMode));
+                } else {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            CONCEPT + key.getID() + DOES_NOT_EXIST);
+                }
+            }
+
+            final Set<AxTask> taskSet = apexModel.getPolicyModel().getTasks().getAll(name, version);
+            if (taskSet.isEmpty()) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
+            }
+
+            final ApexAPIResult result = new ApexAPIResult();
+            for (final AxTask task : taskSet) {
+                result.addMessage(new ApexModelStringWriter<AxTask>(false).writeString(task, AxTask.class, jsonMode));
+                apexModel.getPolicyModel().getTasks().getTaskMap().remove(task.getKey());
+                keyInformationFacade.deleteKeyInformation(name, version);
+            }
+            return result;
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Validate tasks.
+     *
+     * @param name name of the task, set to null to list all
+     * @param version starting version of the task, set to null to list all versions
+     * @return result of the operation
+     */
+    public ApexAPIResult validateTask(final String name, final String version) {
+        try {
+            final Set<AxTask> taskSet = apexModel.getPolicyModel().getTasks().getAll(name, version);
+            if (taskSet.isEmpty()) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
+            }
+
+            final ApexAPIResult result = new ApexAPIResult();
+            for (final AxTask task : taskSet) {
+                final AxValidationResult validationResult = task.validate(new AxValidationResult());
+                result.addMessage(new ApexModelStringWriter<AxArtifactKey>(false).writeString(task.getKey(),
+                        AxArtifactKey.class, jsonMode));
+                result.addMessage(validationResult.toString());
+            }
+            return result;
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Create logic for a task.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to use the latest version
+     * @param logicFlavour the task logic flavour for the task, set to null to use the default task
+     *        logic flavour
+     * @param logic the source code for the logic of the task
+     * @return result of the operation
+     */
+    public ApexAPIResult createTaskLogic(final String name, final String version, final String logicFlavour,
+            final String logic) {
+        try {
+            final AxTask task = apexModel.getPolicyModel().getTasks().get(name, version);
+            if (task == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            // There is only one logic item associated with a task so we use a hard coded logic name
+            final AxReferenceKey refKey = new AxReferenceKey(task.getKey(), "TaskLogic");
+
+            if (!task.getTaskLogic().getKey().getLocalName().equals(AxKey.NULL_KEY_NAME)) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_EXISTS,
+                        CONCEPT + refKey.getID() + ALREADY_EXISTS);
+            }
+
+            task.setTaskLogic(new AxTaskLogic(refKey, logicFlavour, logic));
+            return new ApexAPIResult();
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Update logic for a task.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to use the latest version
+     * @param logicFlavour the task logic flavour for the task, set to null to not update
+     * @param logic the source code for the logic of the task, set to null to not update
+     * @return result of the operation
+     */
+    public ApexAPIResult updateTaskLogic(final String name, final String version, final String logicFlavour,
+            final String logic) {
+        try {
+            final AxTask task = apexModel.getPolicyModel().getTasks().get(name, version);
+            if (task == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            if (task.getTaskLogic().getKey().getLocalName().equals(AxKey.NULL_KEY_NAME)) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + task.getTaskLogic().getKey().getID() + DOES_NOT_EXIST);
+            }
+
+            final AxTaskLogic taskLogic = task.getTaskLogic();
+            if (logicFlavour != null) {
+                taskLogic.setLogicFlavour(logicFlavour);
+            }
+            if (logic != null) {
+                taskLogic.setLogic(logic);
+            }
+
+            return new ApexAPIResult();
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * List task logic.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to list the latest version
+     * @return result of the operation
+     */
+    public ApexAPIResult listTaskLogic(final String name, final String version) {
+        try {
+            final AxTask task = apexModel.getPolicyModel().getTasks().get(name, version);
+            if (task == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            return new ApexAPIResult(ApexAPIResult.RESULT.SUCCESS, new ApexModelStringWriter<AxTaskLogic>(false)
+                    .writeString(task.getTaskLogic(), AxTaskLogic.class, jsonMode));
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Delete logic for a task.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to use the latest version
+     * @return result of the operation
+     */
+    public ApexAPIResult deleteTaskLogic(final String name, final String version) {
+        try {
+            final AxTask task = apexModel.getPolicyModel().getTasks().get(name, version);
+            if (task == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            if (task.getTaskLogic().getKey().getLocalName().equals(AxKey.NULL_KEY_NAME)) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + task.getTaskLogic().getKey().getID() + DOES_NOT_EXIST);
+            }
+
+            final ApexAPIResult result = new ApexAPIResult();
+            result.addMessage(new ApexModelStringWriter<AxTaskLogic>(false).writeString(task.getTaskLogic(),
+                    AxTaskLogic.class, jsonMode));
+            task.setTaskLogic(new AxTaskLogic());
+            return result;
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Create a task input field.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to use the latest version
+     * @param fieldName of the input field
+     * @param contextSchemaName name of the input field context schema
+     * @param contextSchemaVersion version of the input field context schema, set to null to use the
+     *        latest version
+     * @param optional true if the task field is optional, false otherwise
+     * @return result of the operation
+     */
+    public ApexAPIResult createTaskInputField(final String name, final String version, final String fieldName,
+            final String contextSchemaName, final String contextSchemaVersion, final boolean optional) {
+        try {
+            Assertions.argumentNotNull(fieldName, "fieldName may not be null");
+
+            final AxTask task = apexModel.getPolicyModel().getTasks().get(name, version);
+            if (task == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            final AxReferenceKey refKey =
+                    new AxReferenceKey(task.getKey().getName(), task.getKey().getVersion(), "inputFields", fieldName);
+
+            if (task.getInputFields().containsKey(refKey.getLocalName())) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_EXISTS,
+                        CONCEPT + refKey.getID() + ALREADY_EXISTS);
+            }
+
+            final AxContextSchema schema =
+                    apexModel.getPolicyModel().getSchemas().get(contextSchemaName, contextSchemaVersion);
+            if (schema == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + contextSchemaName + ':' + contextSchemaVersion + DOES_NOT_EXIST);
+            }
+
+            task.getInputFields().put(refKey.getLocalName(), new AxInputField(refKey, schema.getKey(), optional));
+            return new ApexAPIResult();
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * List task input fields.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to use the latest version
+     * @param fieldName field name of the input field, set to null to list all input fields of the
+     *        task
+     * @return result of the operation
+     */
+    public ApexAPIResult listTaskInputField(final String name, final String version, final String fieldName) {
+        try {
+            final AxTask task = apexModel.getPolicyModel().getTasks().get(name, version);
+            if (task == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            if (fieldName != null) {
+                final AxInputField inputField = task.getInputFields().get(fieldName);
+                if (inputField != null) {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.SUCCESS,
+                            new ApexModelStringWriter<AxInputField>(false).writeString(inputField, AxInputField.class,
+                                    jsonMode));
+                } else {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            CONCEPT + name + ':' + version + ':' + inputField + DOES_NOT_EXIST);
+                }
+            } else {
+                if (task.getInputFields().size() == 0) {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            "no input fields defined on task " + task.getKey().getID());
+                }
+
+                final ApexAPIResult result = new ApexAPIResult();
+                for (final AxInputField field : task.getInputFields().values()) {
+                    result.addMessage(new ApexModelStringWriter<AxInputField>(false).writeString(field,
+                            AxInputField.class, jsonMode));
+                }
+                return result;
+            }
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+
+    }
+
+    /**
+     * Delete a task input field.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to use the latest version
+     * @param fieldName of the input field, set to null to delete all input fields
+     * @return result of the operation
+     */
+    public ApexAPIResult deleteTaskInputField(final String name, final String version, final String fieldName) {
+        try {
+            final AxTask task = apexModel.getPolicyModel().getTasks().get(name, version);
+            if (task == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            final ApexAPIResult result = new ApexAPIResult();
+            if (fieldName != null) {
+                if (task.getInputFields().containsKey(fieldName)) {
+                    result.addMessage(new ApexModelStringWriter<AxInputField>(false)
+                            .writeString(task.getInputFields().get(fieldName), AxInputField.class, jsonMode));
+                    task.getInputFields().remove(fieldName);
+                    return result;
+                } else {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            CONCEPT + name + ':' + version + ':' + fieldName + DOES_NOT_EXIST);
+                }
+            } else {
+                if (task.getInputFields().size() == 0) {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            "no input fields defined on task " + task.getKey().getID());
+                }
+
+                for (final AxInputField field : task.getInputFields().values()) {
+                    result.addMessage(new ApexModelStringWriter<AxInputField>(false).writeString(field,
+                            AxInputField.class, jsonMode));
+                }
+                task.getInputFields().clear();
+                return result;
+            }
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+
+    }
+
+    /**
+     * Create a task output field.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to use the latest version
+     * @param fieldName of the output field
+     * @param contextSchemaName name of the output field context schema
+     * @param contextSchemaVersion version of the output field context schema, set to null to use
+     *        the latest version
+     * @param optional true if the task field is optional, false otherwise
+     * @return result of the operation
+     */
+    public ApexAPIResult createTaskOutputField(final String name, final String version, final String fieldName,
+            final String contextSchemaName, final String contextSchemaVersion, final boolean optional) {
+        try {
+            Assertions.argumentNotNull(fieldName, "fieldName may not be null");
+
+            final AxTask task = apexModel.getPolicyModel().getTasks().get(name, version);
+            if (task == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            final AxReferenceKey refKey =
+                    new AxReferenceKey(task.getKey().getName(), task.getKey().getVersion(), "outputFields", fieldName);
+
+            if (task.getOutputFields().containsKey(refKey.getLocalName())) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_EXISTS,
+                        CONCEPT + refKey.getID() + ALREADY_EXISTS);
+            }
+
+            final AxContextSchema schema =
+                    apexModel.getPolicyModel().getSchemas().get(contextSchemaName, contextSchemaVersion);
+            if (schema == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + contextSchemaName + ':' + contextSchemaVersion + DOES_NOT_EXIST);
+            }
+
+            task.getOutputFields().put(refKey.getLocalName(), new AxOutputField(refKey, schema.getKey(), optional));
+            return new ApexAPIResult();
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * List task output fields.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to use the latest version
+     * @param fieldName field name of the output field, set to null to list all output fields of the
+     *        task
+     * @return result of the operation
+     */
+    public ApexAPIResult listTaskOutputField(final String name, final String version, final String fieldName) {
+        try {
+            final AxTask task = apexModel.getPolicyModel().getTasks().get(name, version);
+            if (task == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            if (fieldName != null) {
+                final AxOutputField outputField = task.getOutputFields().get(fieldName);
+                if (outputField != null) {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.SUCCESS,
+                            new ApexModelStringWriter<AxOutputField>(false).writeString(outputField,
+                                    AxOutputField.class, jsonMode));
+                } else {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            CONCEPT + name + ':' + version + ':' + outputField + DOES_NOT_EXIST);
+                }
+            } else {
+                if (task.getOutputFields().size() == 0) {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            "no output fields defined on task " + task.getKey().getID());
+                }
+
+                final ApexAPIResult result = new ApexAPIResult();
+                for (final AxOutputField field : task.getOutputFields().values()) {
+                    result.addMessage(new ApexModelStringWriter<AxOutputField>(false).writeString(field,
+                            AxOutputField.class, jsonMode));
+                }
+                return result;
+            }
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Delete a task output field.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to use the latest version
+     * @param fieldName of the output field, set to null to delete all output fields
+     * @return result of the operation
+     */
+    public ApexAPIResult deleteTaskOutputField(final String name, final String version, final String fieldName) {
+        try {
+            final AxTask task = apexModel.getPolicyModel().getTasks().get(name, version);
+            if (task == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            final ApexAPIResult result = new ApexAPIResult();
+            if (fieldName != null) {
+                if (task.getOutputFields().containsKey(fieldName)) {
+                    result.addMessage(new ApexModelStringWriter<AxOutputField>(false)
+                            .writeString(task.getOutputFields().get(fieldName), AxOutputField.class, jsonMode));
+                    task.getOutputFields().remove(fieldName);
+                    return result;
+                } else {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            CONCEPT + name + ':' + version + ':' + fieldName + DOES_NOT_EXIST);
+                }
+            } else {
+                if (task.getOutputFields().size() == 0) {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            "no output fields defined on task " + task.getKey().getID());
+                }
+
+                for (final AxOutputField field : task.getOutputFields().values()) {
+                    result.addMessage(new ApexModelStringWriter<AxOutputField>(false).writeString(field,
+                            AxOutputField.class, jsonMode));
+                }
+                task.getOutputFields().clear();
+                return result;
+            }
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Create a task parameter.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to use the latest version
+     * @param parName of the parameter
+     * @param defaultValue of the parameter
+     * @return result of the operation
+     */
+    public ApexAPIResult createTaskParameter(final String name, final String version, final String parName,
+            final String defaultValue) {
+        try {
+            Assertions.argumentNotNull(parName, "parName may not be null");
+
+            final AxTask task = apexModel.getPolicyModel().getTasks().get(name, version);
+            if (task == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            final AxReferenceKey refKey = new AxReferenceKey(task.getKey(), parName);
+
+            if (task.getTaskParameters().containsKey(refKey.getLocalName())) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_EXISTS,
+                        CONCEPT + refKey.getID() + ALREADY_EXISTS);
+            }
+
+            task.getTaskParameters().put(refKey.getLocalName(), new AxTaskParameter(refKey, defaultValue));
+            return new ApexAPIResult();
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * List task parameters.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to use the latest version
+     * @param parName name of the parameter, set to null to list all parameters of the task
+     * @return result of the operation
+     */
+    public ApexAPIResult listTaskParameter(final String name, final String version, final String parName) {
+        try {
+            final AxTask task = apexModel.getPolicyModel().getTasks().get(name, version);
+            if (task == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            if (parName != null) {
+                final AxTaskParameter taskParameter = task.getTaskParameters().get(parName);
+                if (taskParameter != null) {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.SUCCESS,
+                            new ApexModelStringWriter<AxTaskParameter>(false).writeString(taskParameter,
+                                    AxTaskParameter.class, jsonMode));
+                } else {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            CONCEPT + name + ':' + version + ':' + taskParameter + DOES_NOT_EXIST);
+                }
+            } else {
+                if (task.getTaskParameters().size() == 0) {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            "no task parameters defined on task " + task.getKey().getID());
+                }
+
+                final ApexAPIResult result = new ApexAPIResult();
+                for (final AxTaskParameter parameter : task.getTaskParameters().values()) {
+                    result.addMessage(new ApexModelStringWriter<AxTaskParameter>(false).writeString(parameter,
+                            AxTaskParameter.class, jsonMode));
+                }
+                return result;
+            }
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Delete a task parameter.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to use the latest version
+     * @param parName of the parameter, set to null to delete all task parameters
+     * @return result of the operation
+     */
+    public ApexAPIResult deleteTaskParameter(final String name, final String version, final String parName) {
+        try {
+            final AxTask task = apexModel.getPolicyModel().getTasks().get(name, version);
+            if (task == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            final ApexAPIResult result = new ApexAPIResult();
+            if (parName != null) {
+                if (task.getTaskParameters().containsKey(parName)) {
+                    result.addMessage(new ApexModelStringWriter<AxTaskParameter>(false)
+                            .writeString(task.getTaskParameters().get(parName), AxTaskParameter.class, jsonMode));
+                    task.getTaskParameters().remove(parName);
+                    return result;
+                } else {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            CONCEPT + name + ':' + version + ':' + parName + DOES_NOT_EXIST);
+                }
+            } else {
+                if (task.getTaskParameters().size() == 0) {
+                    return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                            "no task parameters defined on task " + task.getKey().getID());
+                }
+
+                for (final AxTaskParameter parameter : task.getTaskParameters().values()) {
+                    result.addMessage(new ApexModelStringWriter<AxTaskParameter>(false).writeString(parameter,
+                            AxTaskParameter.class, jsonMode));
+                }
+                task.getTaskParameters().clear();
+                return result;
+            }
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Create a task context album reference.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to use the latest version
+     * @param contextAlbumName name of the context album for the context album reference
+     * @param contextAlbumVersion version of the context album for the context album reference, set
+     *        to null to use the latest version
+     * @return result of the operation
+     */
+    public ApexAPIResult createTaskContextRef(final String name, final String version, final String contextAlbumName,
+            final String contextAlbumVersion) {
+        try {
+            final AxTask task = apexModel.getPolicyModel().getTasks().get(name, version);
+            if (task == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            final AxContextAlbum contextAlbum =
+                    apexModel.getPolicyModel().getAlbums().get(contextAlbumName, contextAlbumVersion);
+            if (contextAlbum == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + contextAlbumName + ':' + contextAlbumVersion + DOES_NOT_EXIST);
+            }
+
+            if (task.getContextAlbumReferences().contains(contextAlbum.getKey())) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_EXISTS, "context album reference for concept "
+                        + contextAlbum.getKey().getID() + " already exists in task");
+            }
+
+            task.getContextAlbumReferences().add(contextAlbum.getKey());
+            return new ApexAPIResult();
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * List task context album references.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to use the latest version
+     * @param contextAlbumName name of the context album for the context album reference, set to
+     *        null to list all task context album references
+     * @param contextAlbumVersion version of the context album for the context album reference, set
+     *        to null to use the latest version
+     * @return result of the operation
+     */
+    public ApexAPIResult listTaskContextRef(final String name, final String version, final String contextAlbumName,
+            final String contextAlbumVersion) {
+        try {
+            final AxTask task = apexModel.getPolicyModel().getTasks().get(name, version);
+            if (task == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            final ApexAPIResult result = new ApexAPIResult();
+            boolean found = false;
+            for (final AxArtifactKey albumKey : task.getContextAlbumReferences()) {
+                if (contextAlbumName == null) {
+                    result.addMessage(new ApexModelStringWriter<AxArtifactKey>(false).writeString(albumKey,
+                            AxArtifactKey.class, jsonMode));
+                    found = true;
+                    continue;
+                }
+
+                if (!albumKey.getName().equals(contextAlbumName)) {
+                    continue;
+                }
+
+                if (contextAlbumVersion == null || albumKey.getVersion().equals(contextAlbumVersion)) {
+                    result.addMessage(new ApexModelStringWriter<AxArtifactKey>(false).writeString(albumKey,
+                            AxArtifactKey.class, jsonMode));
+                    found = true;
+                }
+            }
+            if (!found) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + contextAlbumName + ':' + contextAlbumVersion + DOES_NOT_EXIST);
+            }
+            return result;
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+
+    /**
+     * Delete a task context album reference.
+     *
+     * @param name name of the task
+     * @param version version of the task, set to null to use the latest version
+     * @param contextAlbumName name of the context album for the context album reference, set to
+     *        null to delete all task context album references
+     * @param contextAlbumVersion version of the context album for the context album reference, set
+     *        to null to use the latest version
+     * @return result of the operation
+     */
+    public ApexAPIResult deleteTaskContextRef(final String name, final String version, final String contextAlbumName,
+            final String contextAlbumVersion) {
+        try {
+            final AxTask task = apexModel.getPolicyModel().getTasks().get(name, version);
+            if (task == null) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + name + ':' + version + DOES_NOT_EXIST);
+            }
+
+            final Set<AxArtifactKey> deleteSet = new TreeSet<>();
+
+            for (final AxArtifactKey albumKey : task.getContextAlbumReferences()) {
+                if (contextAlbumName == null) {
+                    deleteSet.add(albumKey);
+                    continue;
+                }
+
+                if (!albumKey.getName().equals(contextAlbumName)) {
+                    continue;
+                }
+
+                if (contextAlbumVersion == null || albumKey.getVersion().equals(contextAlbumVersion)) {
+                    deleteSet.add(albumKey);
+                }
+            }
+
+            if (deleteSet.isEmpty()) {
+                return new ApexAPIResult(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST,
+                        CONCEPT + contextAlbumName + ':' + contextAlbumVersion + DOES_NOT_EXIST);
+            }
+            final ApexAPIResult result = new ApexAPIResult();
+            for (final AxArtifactKey keyToDelete : deleteSet) {
+                task.getContextAlbumReferences().remove(keyToDelete);
+                result.addMessage(new ApexModelStringWriter<AxArtifactKey>(false).writeString(keyToDelete,
+                        AxArtifactKey.class, jsonMode));
+            }
+            return result;
+        } catch (final Exception e) {
+            return new ApexAPIResult(ApexAPIResult.RESULT.FAILED, e);
+        }
+    }
+}
diff --git a/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/impl/package-info.java b/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/impl/package-info.java
new file mode 100644
index 0000000..f315420
--- /dev/null
+++ b/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/impl/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 an implementation of the APEX Model API that holds an APEX model and manipulates its
+ * various parts in response to operations called over the Model API.
+ * 
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+package org.onap.policy.apex.model.modelapi.impl;
diff --git a/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/package-info.java b/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/package-info.java
new file mode 100644
index 0000000..97e8db4
--- /dev/null
+++ b/model/model-api/src/main/java/org/onap/policy/apex/model/modelapi/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 an API to APEX models so that they can be manipulated over a common interface by CLI and
+ * GUI based editors and other development tools.
+ * 
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+package org.onap.policy.apex.model.modelapi;
diff --git a/model/model-api/src/test/java/org/onap/policy/apex/model/modelapi/TestAPIResult.java b/model/model-api/src/test/java/org/onap/policy/apex/model/modelapi/TestAPIResult.java
new file mode 100644
index 0000000..e85357f
--- /dev/null
+++ b/model/model-api/src/test/java/org/onap/policy/apex/model/modelapi/TestAPIResult.java
@@ -0,0 +1,80 @@
+/*-
+ * ============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.model.modelapi;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+import org.junit.Test;
+import org.onap.policy.apex.model.modelapi.ApexAPIResult.RESULT;
+
+/**
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class TestAPIResult {
+
+    @Test
+    public void testAPIResult() {
+        assertNotNull(new ApexAPIResult());
+
+        for (final RESULT result : RESULT.values()) {
+            assertNotNull(new ApexAPIResult(result));
+        }
+
+        assertNotNull(new ApexAPIResult(RESULT.SUCCESS, "Result Message"));
+        assertNotNull(new ApexAPIResult(RESULT.FAILED, new IOException("IO Exception message")));
+        assertNotNull(new ApexAPIResult(RESULT.FAILED, "Result Message", new IOException("IO Exception message")));
+
+        final ApexAPIResult result =
+                new ApexAPIResult(RESULT.FAILED, "Result Message", new IOException("IO Exception message"));
+
+        assertFalse(result.isOK());
+        assertTrue(result.isNOK());
+        assertEquals(RESULT.FAILED, result.getResult());
+        assertEquals("Result Message\nIO Exception message\njava.io.IOExce", result.getMessage().substring(0, 50));
+
+        final ApexAPIResult result2 = new ApexAPIResult(RESULT.SUCCESS);
+        result2.addMessage(null);
+        assertEquals("", result2.getMessage());
+        result2.addMessage("");
+        assertEquals("", result2.getMessage());
+        result2.addMessage("funky message");
+        assertEquals("funky message\n", result2.getMessage());
+
+        result2.setResult(RESULT.OTHER_ERROR);
+        assertEquals(RESULT.OTHER_ERROR, result2.getResult());
+
+        final String[] messages = {"First Message", "Second Message", "Third Message"};
+        result2.setMessages(Arrays.asList(messages));
+        assertEquals("First Message", result2.getMessages().get(0));
+        assertEquals("Second Message", result2.getMessages().get(1));
+        assertEquals("Third Message", result2.getMessages().get(2));
+
+        assertEquals("result: OTHER_ERROR\nFirst Message\nSecond Message\nThird Message\n", result2.toString());
+        assertEquals("{\n" + "\"result\": \"OTHER_ERROR\",\n" + "\"messages\": [\n" + "\"First Message\",\n"
+                + "\"Second Message\",\n" + "\"Third Message\"]\n" + "}\n", result2.toJSON());
+    }
+}
diff --git a/model/model-api/src/test/java/org/onap/policy/apex/model/modelapi/TestApexEditorAPIContextAlbum.java b/model/model-api/src/test/java/org/onap/policy/apex/model/modelapi/TestApexEditorAPIContextAlbum.java
new file mode 100644
index 0000000..ad464b1
--- /dev/null
+++ b/model/model-api/src/test/java/org/onap/policy/apex/model/modelapi/TestApexEditorAPIContextAlbum.java
@@ -0,0 +1,173 @@
+/*-
+ * ============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.model.modelapi;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+/**
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class TestApexEditorAPIContextAlbum {
+    @Test
+    public void testContextAlbumCRUD() {
+        final ApexModel apexModel = new ApexModelFactory().createApexModel(null, false);
+
+        ApexAPIResult result = apexModel.validateContextAlbum(null, null);
+        assertEquals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+        result = apexModel.validateContextAlbum("%%%$£", null);
+        assertEquals(ApexAPIResult.RESULT.FAILED, result.getResult());
+
+        result = apexModel.loadFromFile("src/test/resources/models/PolicyModel.json");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.createContextAlbum("MyMap002", "0.0.2", "APPLICATION", "true", "MapType", "0.0.1",
+                "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 002");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createContextAlbum("MyMap012", "0.1.2", "ZOOBY", "false", "MapType", "0.0.1",
+                "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 012");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createContextAlbum("MyMap012", "0.1.4", "UNDEFINED", null, "MapType", "0.0.1",
+                "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 014");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createContextAlbum("MyMap012", null, null, null, null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createContextAlbum("MyMap012", null, "EPHEMERAL", null, null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createContextAlbum("MyMap012", null, "EPHEMERAL", "false", null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createContextAlbum("MyMap012", null, "EPHEMERAL", "false", "", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createContextAlbum("MyMap012", null, "EPHEMERAL", "false", "+++", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createContextAlbum("MyMap012", null, "EPHEMERAL", "false", "MapZooby", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createContextAlbum("MyMap012", null, "EPHEMERAL", "false", "MapType", "--++", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createContextAlbum("MyMap012", null, "EPHEMERAL", "false", "MapType", "0.0.2", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createContextAlbum("MyMap012", null, "EPHEMERAL", "false", "MapType", "0.0.1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createContextAlbum("MyMap012", null, "EPHEMERAL", "false", "MapType", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_EXISTS));
+        result = apexModel.createContextAlbum("MyMap002", "0.0.2", "APPLICATION", "true", "MapType", null,
+                "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 002");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_EXISTS));
+        result = apexModel.createContextAlbum("MyMap011", "0.1.2", "APPLICATION", "true", "MapType", "0.0.1",
+                "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 002");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.deleteContextAlbum("MyMap012", "0.1.2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createContextAlbum("MyMap012", "0.1.2", "ZOOBY", "false", "MapType", "0.0.1",
+                "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 012");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.validateContextAlbum(null, null);
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+
+        result = apexModel.updateContextAlbum(null, null, null, null, null, null, null, null);
+        assertEquals(ApexAPIResult.RESULT.FAILED, result.getResult());
+        result = apexModel.updateContextAlbum("MyMap002", "0.0.2", null, null, null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updateContextAlbum("MyMap002", "0.0.2", "ZOOBY", "true", null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updateContextAlbum("MyMap002", "0.0.2", null, null, null, null,
+                "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 002");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updateContextAlbum("MyMap012", null, null, null, null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updateContextAlbum("MyMap012", null, null, "true", null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updateContextAlbum("MyMap012", null, "APPLICATION", null, null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updateContextAlbum("MyMap015", null, null, null, null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.updateContextAlbum("MyMap014", "0.1.5", null, null, null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.updateContextAlbum("MyMap012", null, "APPLICATION", "false", null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updateContextAlbum("MyMap012", null, "APPLICATION", "false", "StringType", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updateContextAlbum("MyMap012", null, "APPLICATION", "false", "String", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.updateContextAlbum("MyMap012", null, "APPLICATION", "false", "StringType", "0.0.2", null,
+                null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.updateContextAlbum("MyMap012", null, "APPLICATION", "false", "StringType", "0.0.1", null,
+                null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updateContextAlbum("MyMap012", null, "APPLICATION", "Hello", "StringType", "0.0.1", null,
+                null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.listContextAlbum("@£%%$", null);
+        assertEquals(ApexAPIResult.RESULT.FAILED, result.getResult());
+
+        result = apexModel.listContextAlbum(null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listContextAlbum("MyMap012", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listContextAlbum("MyMap012", "0.0.2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listContextAlbum("MyMap012", "0.2.5");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listContextAlbum("MyMap014", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.deleteContextAlbum("@£%%$", null);
+        assertEquals(ApexAPIResult.RESULT.FAILED, result.getResult());
+
+        result = apexModel.deleteContextAlbum("MyMap012", "0.1.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.deleteContextAlbum("MyMap012oooo", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.listContextAlbum("MyMap012", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertTrue(result.getMessages().size() == 3);
+
+        result = apexModel.deleteContextAlbum("MyMap012", "0.1.2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.listContextAlbum("MyMap012", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertTrue(result.getMessages().size() == 2);
+
+        result = apexModel.deleteContextAlbum("MyMap012", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.listContextAlbum("MyMap012", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.deleteContextAlbum(null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(4, result.getMessages().size());
+
+        result = apexModel.listContextAlbum(null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(0, result.getMessages().size());
+    }
+}
diff --git a/model/model-api/src/test/java/org/onap/policy/apex/model/modelapi/TestApexEditorAPIContextSchema.java b/model/model-api/src/test/java/org/onap/policy/apex/model/modelapi/TestApexEditorAPIContextSchema.java
new file mode 100644
index 0000000..7eb85da
--- /dev/null
+++ b/model/model-api/src/test/java/org/onap/policy/apex/model/modelapi/TestApexEditorAPIContextSchema.java
@@ -0,0 +1,152 @@
+/*-
+ * ============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.model.modelapi;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+/**
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class TestApexEditorAPIContextSchema {
+    @Test
+    public void testContextSchemaCRUD() {
+        final ApexModel apexModel = new ApexModelFactory().createApexModel(null, false);
+
+        ApexAPIResult result = apexModel.validateContextSchemas(null, null);
+        assertEquals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+        result = apexModel.validateContextSchemas("%%%$£", null);
+        assertEquals(ApexAPIResult.RESULT.FAILED, result.getResult());
+
+        result = apexModel.loadFromFile("src/test/resources/models/PolicyModel.json");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listContextSchemas(null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.createContextSchema("Hello", "0.0.2", "Java", "java.lang.String",
+                "1fa2e430-f2b2-11e6-bc64-92361f002671", "A description of hello");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createContextSchema("Hello", "0.1.2", "Java", "java.lang.String",
+                "1fa2e430-f2b2-11e6-bc64-92361f002672", "A description of hola");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createContextSchema("Hello", "0.1.4", "Java", "java.lang.String",
+                "1fa2e430-f2b2-11e6-bc64-92361f002672", "A description of connichi wa");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createContextSchema("Hello", null, "Java", "java.lang.String", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createContextSchema("Hello", null, "Java", "java.lang.String", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_EXISTS));
+        result = apexModel.deleteContextSchema("Hello", "0.1.4");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createContextSchema("Hello", "0.1.4", "Java", "java.lang.String",
+                "1fa2e430-f2b2-11e6-bc64-92361f002672", "A description of connichi wa");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.createContextSchema("Hello2", null, null, "java.lang.String", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createContextSchema("Hello2", null, null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createContextSchema("Hello2", null, "Java", "java.lang.String", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.createContextSchema("Hello", "0.1.2", "Java", "java.lang.Float",
+                "1fa2e430-f2b2-11e6-bc64-92361f002672", "A description of hola");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_EXISTS));
+
+        result = apexModel.deleteContextSchema("Hello", "0.1.4");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createContextSchema("Hello", "0.1.4", "Java", "java.lang.String",
+                "1fa2e430-f2b2-11e6-bc64-92361f002672", "A description of connichi wa");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.validateContextSchemas(null, null);
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+
+        result = apexModel.updateContextSchema(null, null, null, null, null, null);
+        assertEquals(ApexAPIResult.RESULT.FAILED, result.getResult());
+
+        result = apexModel.updateContextSchema("Hello", "0.0.2", null, null, null, "An updated description of hello");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updateContextSchema("Hello", "0.0.2", null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updateContextSchema("Hello", "0.1.2", "Java", "java.lang.Integer",
+                "1fa2e430-f2b2-11e6-bc64-92361f002673", "A further updated description of hola");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.updateContextSchema("Hello2", "0.0.2", null, null, null, "An updated description of hello");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.listContextSchemas("@£%%$", null);
+        assertEquals(ApexAPIResult.RESULT.FAILED, result.getResult());
+
+        result = apexModel.listContextSchemas("Hello", "0.1.2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertTrue(result.getMessages().size() == 2);
+
+        result = apexModel.listContextSchemas("Hello", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertTrue(result.getMessages().size() == 4);
+
+        result = apexModel.listContextSchemas(null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertTrue(result.getMessages().size() == 9);
+
+        result = apexModel.deleteContextSchema("@£%%$", null);
+        assertEquals(ApexAPIResult.RESULT.FAILED, result.getResult());
+
+        result = apexModel.deleteContextSchema("Hello", "0.1.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.deleteContextSchema("Hellooooo", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.listContextSchemas("Hello", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertTrue(result.getMessages().size() == 4);
+
+        result = apexModel.deleteContextSchema("Hello", "0.1.2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.listContextSchemas("Hello", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertTrue(result.getMessages().size() == 3);
+
+        result = apexModel.deleteContextSchema("Hello", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.listContextSchemas("Hello", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.listContextSchemas(null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.deleteContextSchema(null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(5, result.getMessages().size());
+
+        result = apexModel.listContextSchemas(null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(0, result.getMessages().size());
+    }
+}
diff --git a/model/model-api/src/test/java/org/onap/policy/apex/model/modelapi/TestApexEditorAPIEvent.java b/model/model-api/src/test/java/org/onap/policy/apex/model/modelapi/TestApexEditorAPIEvent.java
new file mode 100644
index 0000000..da9f48c
--- /dev/null
+++ b/model/model-api/src/test/java/org/onap/policy/apex/model/modelapi/TestApexEditorAPIEvent.java
@@ -0,0 +1,196 @@
+/*-
+ * ============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.model.modelapi;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+/**
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class TestApexEditorAPIEvent {
+    @Test
+    public void testEventCRUD() {
+        final ApexModel apexModel = new ApexModelFactory().createApexModel(null, false);
+
+        ApexAPIResult result = apexModel.validateEvent(null, null);
+        assertEquals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+        result = apexModel.validateEvent("%%%$£", null);
+        assertEquals(ApexAPIResult.RESULT.FAILED, result.getResult());
+
+        result = apexModel.loadFromFile("src/test/resources/models/PolicyModel.json");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.createEvent("MyEvent002", "0.0.2", "My Namespace", "My Source", "my target",
+                "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 002");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createEvent("MyEvent012", "0.1.2", "My Namespace", "My Source", "my target",
+                "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 012");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createEvent("MyEvent012", "0.1.4", "My Namespace", "My Source", "my target",
+                "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 014");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createEvent("MyEvent012", null, null, null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createEvent("MyEvent012", null, null, null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_EXISTS));
+        result = apexModel.createEvent("MyEvent002", "0.0.2", "My Namespace", "My Source", "my target",
+                "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 002");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_EXISTS));
+        result = apexModel.createEvent("@£$%^", "0.2.5", "My Namespace", "My Source", "my target",
+                "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 002");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+
+        result = apexModel.deleteEvent("MyEvent012", "0.1.4");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createEvent("MyEvent012", "0.1.4", "My Namespace", "My Source", "my target",
+                "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 014");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.validateEvent(null, null);
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+
+        result = apexModel.updateContextSchema(null, null, null, null, null, null);
+        assertEquals(ApexAPIResult.RESULT.FAILED, result.getResult());
+        result = apexModel.updateEvent("MyEvent012", "0.1.2", "Another Namespace", null, "Another target", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updateEvent("MyEvent002", "0.0.2", "My Namespace", "My Source", "my target",
+                "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 002");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updateEvent("MyEvent012", null, null, null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updateEvent("MyEvent015", null, null, null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.updateEvent("MyEvent014", "0.1.5", null, null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.updateEvent("@£$%^^", "0.6.9", null, null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+
+        result = apexModel.listEvent("@£$%", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.listEvent(null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listEvent("MyEvent012", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listEvent("MyEvent012", "0.0.2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listEvent("MyEvent012", "0.2.5");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listEvent("MyEvent123", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.deleteEvent("@£$%^", "0.1.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.deleteEvent("MyEvent012", "0.1.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.deleteEvent("MyEvent012oooo", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.listEvent("MyEvent012", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertTrue(result.getMessages().size() == 3);
+
+        result = apexModel.deleteEvent("MyEvent012", "0.1.2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.listEvent("MyEvent012", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertTrue(result.getMessages().size() == 2);
+
+        result = apexModel.deleteEvent("MyEvent012", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.listEvent("MyEvent012", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.createEventPar("MyEvent123", null, "NewPar00", null, null, false);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.createEventPar("MyEvent002", "4.5.6", "NewPar00", null, null, true);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.createEventPar("MyEvent002", "0.1.4", "NewPar00", null, null, false);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.createEventPar("MyEvent002", "0.0.2", "NewPar00", null, null, true);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+
+        result = apexModel.createEventPar("MyEvent002", "0.0.2", "NewPar00", "eventContextItem0", null, false);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createEventPar("MyEvent002", "0.0.2", "NewPar00", "eventContextItem0", null, true);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_EXISTS));
+        result = apexModel.createEventPar("MyEvent002", "0.0.2", "NewPar01", "eventContextItem0", "0.0.1", false);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createEventPar("MyEvent002", "0.0.2", "NewPar02", "eventContextItem0", "0.0.2", true);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createEventPar("MyEvent002", null, "NewPar02", "eventContextItem0", null, false);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createEventPar("MyEvent002", null, "NewPar03", "eventContextItem0", null, true);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.listEventPar("@£%%$", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.listEventPar("MyEvent002", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listEventPar("MyEvent002", "0.0.1", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listEventPar("MyEvent002", "0.0.2", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listEventPar("MyEvent002", "0.0.2", "NewPar01");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listEventPar("MyEvent002", "0.0.2", "NewPar02");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listEventPar("MyEvent002", "0.0.2", "NewPar04");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.deleteEventPar("@££%%%", "0.0.2", "NewPar04");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.deleteEventPar("NonExistantEvent", "0.0.2", "NewPar04");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        assertEquals(4, apexModel.listEventPar("MyEvent002", null, null).getMessages().size());
+        result = apexModel.deleteEventPar("MyEvent002", "0.0.2", "NewPar04");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        assertEquals(4, apexModel.listEventPar("MyEvent002", null, null).getMessages().size());
+        result = apexModel.deleteEventPar("MyEvent002", null, "NewPar02");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(3, apexModel.listEventPar("MyEvent002", null, null).getMessages().size());
+        result = apexModel.deleteEventPar("MyEvent002", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listEventPar("MyEvent002", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deleteEventPar("MyEvent002", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listEventPar("MyEvent002", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.deleteEvent(null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(4, result.getMessages().size());
+
+        result = apexModel.listEvent(null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(0, result.getMessages().size());
+    }
+}
diff --git a/model/model-api/src/test/java/org/onap/policy/apex/model/modelapi/TestApexEditorAPIKeyInfo.java b/model/model-api/src/test/java/org/onap/policy/apex/model/modelapi/TestApexEditorAPIKeyInfo.java
new file mode 100644
index 0000000..c755b90
--- /dev/null
+++ b/model/model-api/src/test/java/org/onap/policy/apex/model/modelapi/TestApexEditorAPIKeyInfo.java
@@ -0,0 +1,136 @@
+/*-
+ * ============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.model.modelapi;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+/**
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class TestApexEditorAPIKeyInfo {
+
+    @Test
+    public void testKeyInfoCRUD() {
+        final ApexModel apexModel = new ApexModelFactory().createApexModel(null, false);
+
+        ApexAPIResult result = apexModel.validateKeyInformation(null, null);
+        assertEquals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+        result = apexModel.validateKeyInformation("%%%$£", null);
+        assertEquals(ApexAPIResult.RESULT.FAILED, result.getResult());
+
+        result = apexModel.loadFromFile("src/test/resources/models/PolicyModel.json");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.createKeyInformation(null, null, null, null);
+        assertEquals(ApexAPIResult.RESULT.FAILED, result.getResult());
+
+        result = apexModel.createKeyInformation("Hello", "0.0.2", "1fa2e430-f2b2-11e6-bc64-92361f002671",
+                "A description of hello");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createKeyInformation("Hello", "0.1.2", "1fa2e430-f2b2-11e6-bc64-92361f002672",
+                "A description of hola");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createKeyInformation("Hello", "0.1.4", "1fa2e430-f2b2-11e6-bc64-92361f002672",
+                "A description of connichi wa");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createKeyInformation("Hello", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createKeyInformation("Hello", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_EXISTS));
+
+        result = apexModel.createKeyInformation("Hello", "0.1.2", "1fa2e430-f2b2-11e6-bc64-92361f002672",
+                "A description of hola");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_EXISTS));
+
+        result = apexModel.validateKeyInformation(null, null);
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+
+        result = apexModel.updateKeyInformation(null, null, null, null);
+        assertEquals(ApexAPIResult.RESULT.FAILED, result.getResult());
+
+        result = apexModel.updateKeyInformation("Hello", "0.0.2", null, "An updated description of hello");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updateKeyInformation("Hello", "0.0.2", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updateKeyInformation("Hello", "0.1.2", "1fa2e430-f2b2-11e6-bc64-92361f002673",
+                "A further updated description of hola");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.updateKeyInformation("Hello2", "0.0.2", null, "An updated description of hello");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.listKeyInformation(null, null);
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+
+        result = apexModel.listKeyInformation("%%%$$", null);
+        assertEquals(ApexAPIResult.RESULT.FAILED, result.getResult());
+
+        result = apexModel.listKeyInformation("Hello", "0.1.2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertTrue(result.getMessages().size() == 2);
+
+        result = apexModel.listKeyInformation("Hello", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertTrue(result.getMessages().size() == 4);
+
+        result = apexModel.deleteKeyInformation("Hello", "0.1.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.deleteKeyInformation("Hellooooo", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.listKeyInformation("Hello", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertTrue(result.getMessages().size() == 4);
+
+        result = apexModel.listKeyInformation(null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertTrue(result.getMessages().size() == 22);
+
+        result = apexModel.deleteKeyInformation("%%%$$", null);
+        assertEquals(ApexAPIResult.RESULT.FAILED, result.getResult());
+
+        result = apexModel.deleteKeyInformation("Hello", "0.1.2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.listKeyInformation("Hello", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertTrue(result.getMessages().size() == 3);
+
+        result = apexModel.deleteKeyInformation("Hello", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.listKeyInformation("Hello", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.deleteKeyInformation(null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(18, result.getMessages().size());
+
+        result = apexModel.listKeyInformation(null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(0, result.getMessages().size());
+    }
+}
diff --git a/model/model-api/src/test/java/org/onap/policy/apex/model/modelapi/TestApexEditorAPIPolicy.java b/model/model-api/src/test/java/org/onap/policy/apex/model/modelapi/TestApexEditorAPIPolicy.java
new file mode 100644
index 0000000..94861f9
--- /dev/null
+++ b/model/model-api/src/test/java/org/onap/policy/apex/model/modelapi/TestApexEditorAPIPolicy.java
@@ -0,0 +1,1022 @@
+/*-
+ * ============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.model.modelapi;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+/**
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class TestApexEditorAPIPolicy {
+    @Test
+    public void MyTestPolicyCRUD() {
+        final ApexModel apexModel = new ApexModelFactory().createApexModel(null, false);
+
+        ApexAPIResult result = apexModel.validatePolicy(null, null);
+        assertEquals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+        result = apexModel.validatePolicy("%%%$£", null);
+        assertEquals(ApexAPIResult.RESULT.FAILED, result.getResult());
+
+        result = apexModel.loadFromFile("src/test/resources/models/PolicyModel.json");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.createPolicy("MyPolicy002", "0.0.2", "SomeTemplate", "AState",
+                "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 002");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicy("MyPolicy002", "0.0.2", "SomeTemplate", "AState",
+                "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 002");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_EXISTS));
+        result = apexModel.createPolicy("MyPolicy012", null, null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createPolicy("MyPolicy012", null, "SomeTemplate", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createPolicy("MyPolicy013", null, null, "AState", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicy("MyPolicy012", null, "SomeTemplate", "AState", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicy("MyPolicy002", "0.0.2", "SomeTemplate", "AState",
+                "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 002");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_EXISTS));
+        result = apexModel.createPolicy("MyPolicy012", "0.1.2", "SomeTemplate", "AState",
+                "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 002");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicy("MyTestPolicy", "0.0.1", "SomeTemplate", "TestState",
+                "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 002");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.deletePolicy("MyPolicy002", "0.0.2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicy("MyPolicy002", "0.0.2", "SomeTemplate", "AState",
+                "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 002");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.validatePolicy(null, null);
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+
+        result = apexModel.updatePolicy("@£$$", "0.0.2", null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.updatePolicy("MyPolicy002", "0.0.2", null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updatePolicy("MyPolicy002", "0.0.1", null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.updatePolicy("MyPolicy002", "0.0.2", "SomeOtherTemplate", "BState",
+                "1fa2e430-f2b2-11e6-bc64-92361f002700", "A description of 002");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updatePolicy("MyPolicy012", null, "SomeOtherTemplate", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updatePolicy("MyPolicy012", null, null, "CState", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updatePolicy("MyPolicy012", null, "SomeOtherTemplate", "BState", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updatePolicy("MyPolicy015", null, "SomeOtherTemplate", "DState", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.updatePolicy("MyPolicy014", "0.1.5", "SomeOtherTemplate", "EState", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.listPolicy("@£$%%", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.listPolicy(null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(6, result.getMessages().size());
+        result = apexModel.listPolicy("MyPolicy012", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(2, result.getMessages().size());
+        result = apexModel.listPolicy("MyPolicy012", "0.0.2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(1, result.getMessages().size());
+        result = apexModel.listPolicy("MyPolicy012", "0.2.5");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicy("MyPolicy014", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.deletePolicy("@£$%", "0.1.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+
+        result = apexModel.deletePolicy("MyPolicy012", "0.1.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.deletePolicy("MyPolicy012oooo", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.listPolicy("MyPolicy012", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertTrue(result.getMessages().size() == 2);
+
+        result = apexModel.deletePolicy("MyPolicy002", "0.0.2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertTrue(result.getMessages().size() == 1);
+
+        result = apexModel.listPolicy("MyPolicy012", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertTrue(result.getMessages().size() == 2);
+
+        result = apexModel.deletePolicy("MyPolicy012", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertTrue(result.getMessages().size() == 2);
+
+        result = apexModel.createPolicyState(null, null, null, null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createPolicyState("MyPolicy123", null, null, null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createPolicyState("MyPolicy123", null, "AState", null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createPolicyState("MyTestPolicy", "0.0.2", "AState", null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createPolicyState("MyTestPolicy", null, "AState", null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createPolicyState("MyTestPolicy", null, "AState", "ATrigger", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createPolicyState("MyTestPolicy", null, "AState", "inEvent", "0.0.2", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createPolicyState("MyTestPolicy", null, "AState", "inEvent", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createPolicyState("MyTestPolicy", null, "AState", "inEvent", "0.0.1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createPolicyState("MyTestPolicy", null, "AState", "inEvent", null, "ATask", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createPolicyState("MyTestPolicy", null, "AState", "inEvent", null, "task", "0.0.2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createPolicyState("MyTestPolicy", null, "AState", "inEvent", null, "task", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicyState("MyTestPolicy", null, "AState", "inEvent", null, "task", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_EXISTS));
+        result = apexModel.createPolicyState("MyTestPolicy", "0.0.1", "AState", "inEvent", "0.0.1", "task", "0.0.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_EXISTS));
+        result = apexModel.createPolicyState("MyTestPolicy", "0.0.1", "BState", "inEvent", "0.0.1", "task", "0.0.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicyState("MyTestPolicy", "0.0.1", "CState", "inEvent", "0.0.1", "task", "0.0.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicyState("MyTestPolicy", "0.0.1", "DState", "inEvent", "0.0.1", "task", "0.0.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.updatePolicyState(null, null, null, null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.updatePolicyState("MyPolicy123", null, null, null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.updatePolicyState("MyPolicy123", null, "AState", null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.updatePolicyState("MyTestPolicy", "0.0.2", "AState", null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.updatePolicyState("MyTestPolicy", null, "AState", null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updatePolicyState("MyTestPolicy", null, "ZState", null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.updatePolicyState("MyTestPolicy", null, "AState", "ATrigger", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.updatePolicyState("MyTestPolicy", null, "AState", "inEvent", "0.0.2", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.updatePolicyState("MyTestPolicy", null, "AState", "inEvent", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updatePolicyState("MyTestPolicy", null, "AState", "inEvent", "0.0.2", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.updatePolicyState("MyTestPolicy", null, "AState", "inEvent", null, "ATask", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.updatePolicyState("MyTestPolicy", null, "AState", "inEvent", null, "task", "0.0.2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.updatePolicyState("MyTestPolicy", null, "AState", "inEvent", null, "task", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updatePolicyState("MyTestPolicy", null, "AState", "inEvent", null, "task", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updatePolicyState("MyTestPolicy", "0.0.1", "AState", "inEvent", "0.0.1", "task", "0.0.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updatePolicyState("MyTestPolicy", "0.0.1", "BState", "inEvent", "0.0.1", "task", "0.0.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updatePolicyState("MyTestPolicy", "0.0.1", "CState", "inEvent", "0.0.1", "task", "0.0.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updatePolicyState("MyTestPolicy", "0.0.1", "DState", "inEvent", "0.0.1", "task", "0.0.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.listPolicyState("MyTestPolicy", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(4, result.getMessages().size());
+        result = apexModel.listPolicyState(null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.listPolicyState("SomeOtherPolicy", "0.0.1", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyState("SomeOtherPolicy", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyState("MyTestPolicy", "0.0.2", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyState("MyTestPolicy", "0.0.1", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(4, result.getMessages().size());
+        result = apexModel.listPolicyState("MyTestPolicy", "0.0.1", "CState");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(1, result.getMessages().size());
+        result = apexModel.listPolicyState("MyTestPolicy", null, "CState");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(1, result.getMessages().size());
+        result = apexModel.listPolicyState("MyTestPolicy", "0.0.1", "AState");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(1, result.getMessages().size());
+        result = apexModel.listPolicyState("MyTestPolicy", "0.0.1", "EState");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.deletePolicyState("@£$$", "0.0.2", "Trigger04");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        assertEquals(4, apexModel.listPolicyState("MyTestPolicy", null, null).getMessages().size());
+        result = apexModel.deletePolicyState("MyTestPolicy", "0.0.2", "Trigger04");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        assertEquals(4, apexModel.listPolicyState("MyTestPolicy", null, null).getMessages().size());
+        result = apexModel.deletePolicyState("MyTestPolicy", null, "CState");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.deletePolicyState("MyTestPolicy", null, "ZState");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        assertEquals(3, apexModel.listPolicyState("MyTestPolicy", null, null).getMessages().size());
+        result = apexModel.deletePolicyState("MyTestPolicy", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listPolicyState("MyTestPolicy", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deletePolicyState("MyTestPolicy", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.createPolicyState("MyTestPolicy", "0.0.1", "TestState1", "inEvent", "0.0.1", "task",
+                "0.0.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.createPolicyState("MyTestPolicy", "0.0.1", "TestState2", "outEvent0", "0.0.1", "task",
+                "0.0.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.createPolicyState("MyTestPolicy", "0.0.1", "TestState3", "outEvent1", "0.0.1", "task",
+                "0.0.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.createPolicyStateTaskSelectionLogic(null, null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createPolicyStateTaskSelectionLogic("MyTestPolicy", null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createPolicyStateTaskSelectionLogic("MyTestPolicy", null, "SomeState", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createPolicyStateTaskSelectionLogic("MyTestPolicy", "1.2.3", "TestState1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createPolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.1", "TestState1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createPolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.1", "TestState1", "NewTSL00", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createPolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.1", "TestState1", "UNDEFINED",
+                "Some Policy Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.1", "TestState1", "MVEL",
+                "Some Policy Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_EXISTS));
+
+        result = apexModel.deletePolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.1", "TestState1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.1", "TestState1", "JAVA",
+                "Some Policy Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.1", "TestState1", "JYTHON",
+                "Some Policy Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_EXISTS));
+        result = apexModel.deletePolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.1", "TestState1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicyStateTaskSelectionLogic("MyTestPolicy", null, "TestState1", "JAVASCRIPT",
+                "Some Policy Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.deletePolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.1", "TestState1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicyStateTaskSelectionLogic("MyTestPolicy", null, "TestState1", "JRUBY",
+                "Some Policy Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.updatePolicyStateTaskSelectionLogic(null, null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.updatePolicyStateTaskSelectionLogic("MyTestPolicy", null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.updatePolicyStateTaskSelectionLogic("MyTestPolicy", null, "TestState1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updatePolicyStateTaskSelectionLogic("MyTestPolicy", null, "TestState99", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.updatePolicyStateTaskSelectionLogic("MyTestPolicy2", null, "TestState1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.updatePolicyStateTaskSelectionLogic("MyTestPolicy1", "0.0.2", "TestState1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.updatePolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.1", "TestState1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updatePolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.1", "NonExistantState", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.updatePolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.1", "TestState1", "",
+                "Some Other Policy Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.updatePolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.1", "TestState1", "MVEL",
+                "Some Other Policy Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updatePolicyStateTaskSelectionLogic("MyPolicy012", null, "TestState1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.updatePolicyStateTaskSelectionLogic("MyTestPolicy", null, "TestState1", null,
+                "Some Other Policy Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updatePolicyStateTaskSelectionLogic("MyTestPolicy", null, "TestState1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updatePolicyStateTaskSelectionLogic("MyPolicy015", null, "TestState1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.updatePolicyStateTaskSelectionLogic("MyPolicy014", "0.1.5", "TestState1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.listPolicyStateTaskSelectionLogic(null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.listPolicyStateTaskSelectionLogic("zooby", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.listPolicyStateTaskSelectionLogic("zooby", null, "looby");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateTaskSelectionLogic("zooby", null, "TestState1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateTaskSelectionLogic("MyTestPolicy", null, "looby");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.2", "TestState1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateTaskSelectionLogic("MyTestPolicy", null, "TestState1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(1, result.getMessages().size());
+
+        result = apexModel.deletePolicyStateTaskSelectionLogic(null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.deletePolicyStateTaskSelectionLogic("zooby", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.deletePolicyStateTaskSelectionLogic("zooby", null, "looby");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deletePolicyStateTaskSelectionLogic("zooby", null, "TestState1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deletePolicyStateTaskSelectionLogic("MyTestPolicy", null, "looby");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deletePolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.2", "TestState1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deletePolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.1", "TestState1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listPolicyStateTaskSelectionLogic("MyTestPolicy", null, "TestState1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.deletePolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.1", "TestState1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.updatePolicyStateTaskSelectionLogic("MyTestPolicy", null, "TestState1", null,
+                "Some Other Policy Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateTaskSelectionLogic("MyTestPolicy", null, "TestState1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(1, result.getMessages().size());
+        result = apexModel.createPolicyStateTaskSelectionLogic("MyTestPolicy", null, "TestState1", "JRUBY",
+                "Some Policy Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listPolicyStateTaskSelectionLogic("MyTestPolicy", null, "TestState1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.deletePolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.1", "TestState1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.deletePolicyStateTaskSelectionLogic("MyTestPolicy", "0.0.1", "TestState1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.createPolicyStateOutput(null, null, null, null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createPolicyStateOutput("MyTestPolicy", null, null, null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createPolicyStateOutput("MyTestPolicy", null, "SomeState", null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createPolicyStateOutput("MyTestPolicy", null, "SomeState", "SomeOutput", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createPolicyStateOutput("MyTestPolicy", "1.2.3", "TestState1", "SomeOutput", null, null,
+                null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState1", "SomeOutput", null, null,
+                null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState1", "SomeOutput",
+                "SomeDummyEvent", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState1", "SomeOutput", "inEvent",
+                "1.2.3", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState1", "SomeOutput", "inEvent",
+                "0.0.1", "SomeDummyNextState");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState1", "SomeOutput", "inEvent",
+                "0.0.1", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState1", "SomeOtherOutput", "inEvent",
+                "0.0.1", "TestState1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState1", "SomeOtherOutput", "inEvent",
+                "0.0.1", "TestState2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState1", "SomeOtherOutput", "inEvent",
+                "0.0.1", "TestState2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_EXISTS));
+        result = apexModel.createPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState2", "AnotherOtherOutput",
+                "outEvent0", "0.0.1", "TestState3");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState2", "YetAnotherOtherOutput",
+                "outEvent0", "0.0.1", "TestState3");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.listPolicyStateOutput(null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.listPolicyStateOutput("MyTestPolicy", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.listPolicyStateOutput("MyTestPolicy", "0.0.1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.listPolicyStateOutput("MyTestPolicy", "0.0.2", "TestState1", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateOutput("MyTestPolicy", null, "SomeState", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateOutput("MyTestPolicy", "0.0.1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.listPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState1", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(2, result.getMessages().size());
+        result = apexModel.listPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState2", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(2, result.getMessages().size());
+        result = apexModel.listPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState1", "YetAnotherOtherOutput");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState2", "YetAnotherOtherOutput");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(1, result.getMessages().size());
+        result = apexModel.listPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState3", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.deletePolicyStateOutput(null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.deletePolicyStateOutput("MyTestPolicy", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.deletePolicyStateOutput("MyTestPolicy", "0.0.1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.deletePolicyStateOutput("MyTestPolicy", "0.0.2", "TestState1", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deletePolicyStateOutput("MyTestPolicy", null, "SomeState", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deletePolicyStateOutput("MyTestPolicy", "0.0.1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.deletePolicyStateOutput("MyTestPolicy", "0.0.1", "TestState3", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deletePolicyStateOutput("MyTestPolicy", "0.0.1", "TestState3", "DummyOutput");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateOutput("MyTestPolicy", null, "TestState1", null);
+        assertEquals(2, result.getMessages().size());
+        result = apexModel.deletePolicyStateOutput("MyTestPolicy", null, "TestState1", "SomeOutput");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(1, result.getMessages().size());
+        result = apexModel.listPolicyStateOutput("MyTestPolicy", null, "TestState1", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(1, result.getMessages().size());
+        result = apexModel.deletePolicyStateOutput("MyTestPolicy", null, "TestState1", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(1, result.getMessages().size());
+        result = apexModel.listPolicyStateOutput("MyTestPolicy", null, "TestState1", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateOutput("MyTestPolicy", null, "TestState2", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(2, result.getMessages().size());
+        result = apexModel.deletePolicyStateOutput("MyTestPolicy", null, "TestState2", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(2, result.getMessages().size());
+        result = apexModel.listPolicyStateOutput("MyTestPolicy", null, "TestState2", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.createPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState1", "SomeOutput", "inEvent",
+                "0.0.1", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState1", "SomeOtherOutput", "inEvent",
+                "0.0.1", "TestState1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState1", "SomeOtherOutput", "inEvent",
+                "0.0.1", "TestState2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState2", "AnotherOtherOutput",
+                "outEvent0", "0.0.1", "TestState3");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicyStateOutput("MyTestPolicy", "0.0.1", "TestState2", "YetAnotherOtherOutput",
+                "outEvent0", "0.0.1", "TestState3");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.createPolicyStateFinalizerLogic(null, null, null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", null, null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", null, "SomeState", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", null, "SomeState", "SFLName01", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", "1.2.3", "TestState1", "SFLName01", null,
+                null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "SFLName01", null,
+                null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "SFLName01",
+                "NewTSL00", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "SFLName02",
+                "UNDEFINED", "Some Policy Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "SFLName03", "MVEL",
+                "Some Policy Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "SFLName03", "MVEL",
+                "Some Policy Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_EXISTS));
+        result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "SFLName04", "JAVA",
+                "Some Policy Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "SFLName05", "JYTHON",
+                "Some Policy Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", null, "TestState1", "SFLName06",
+                "JAVASCRIPT", "Some Policy Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", null, "TestState1", "SFLName07", "JRUBY",
+                "Some Policy Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.updatePolicyStateFinalizerLogic(null, null, null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.updatePolicyStateFinalizerLogic("MyTestPolicy", null, null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.updatePolicyStateFinalizerLogic("MyTestPolicy", null, "TestState1", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.updatePolicyStateFinalizerLogic("MyTestPolicy", null, "TestState99", "SomeSFLName", null,
+                null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.updatePolicyStateFinalizerLogic("MyTestPolicy2", null, "TestState1", "SomeSFLName", null,
+                null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.updatePolicyStateFinalizerLogic("MyTestPolicy1", "0.0.2", "TestState1", "SomeSFLName", null,
+                null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.updatePolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "NonEistantSFL", null,
+                null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.updatePolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "SFLName06", null,
+                null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updatePolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "SFLName06", "",
+                "Some Other Policy Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.updatePolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "SFLName06", "MVEL",
+                "Some Other Policy Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updatePolicyStateFinalizerLogic("MyPolicy012", null, "TestState1", "SFLName06", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.updatePolicyStateFinalizerLogic("MyTestPolicy", null, "TestState1", "SFLName06", null,
+                "Some Other Policy Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updatePolicyStateFinalizerLogic("MyTestPolicy", null, "TestState1", "SFLName06", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updatePolicyStateFinalizerLogic("MyPolicy015", null, "TestState1", "SFLName06", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.updatePolicyStateFinalizerLogic("MyPolicy014", "0.1.5", "TestState1", "SFLName06", null,
+                null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.listPolicyStateFinalizerLogic(null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.listPolicyStateFinalizerLogic("MyTestPolicy", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.listPolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.listPolicyStateFinalizerLogic("MyTestPolicy", "0.0.2", "TestState1", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateFinalizerLogic("MyTestPolicy", null, "SomeState", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.listPolicyStateFinalizerLogic("zooby", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.listPolicyStateFinalizerLogic("zooby", null, "looby", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateFinalizerLogic("zooby", null, "TestState1", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateFinalizerLogic("MyTestPolicy", null, "looby", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateFinalizerLogic("MyTestPolicy", "0.0.2", "TestState1", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateFinalizerLogic("MyTestPolicy", null, "TestState1", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(6, result.getMessages().size());
+        result = apexModel.listPolicyStateFinalizerLogic("MyTestPolicy", null, "TestState1", "SFLName06");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(1, result.getMessages().size());
+
+        result = apexModel.deletePolicyStateFinalizerLogic(null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.deletePolicyStateFinalizerLogic("MyTestPolicy", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.deletePolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.deletePolicyStateFinalizerLogic("MyTestPolicy", "0.0.2", "TestState1", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deletePolicyStateFinalizerLogic("MyTestPolicy", null, "SomeState", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deletePolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.deletePolicyStateFinalizerLogic("zooby", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.deletePolicyStateFinalizerLogic("zooby", null, "looby", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deletePolicyStateFinalizerLogic("zooby", null, "TestState1", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deletePolicyStateFinalizerLogic("MyTestPolicy", null, "looby", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deletePolicyStateFinalizerLogic("MyTestPolicy", "0.0.2", "TestState1", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deletePolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "SFLName06");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.deletePolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "SFLName06");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        assertEquals(1, result.getMessages().size());
+        result = apexModel.listPolicyStateFinalizerLogic("MyTestPolicy", null, "TestState1", "SFLName06");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateFinalizerLogic("MyTestPolicy", null, "TestState1", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(5, result.getMessages().size());
+        result = apexModel.deletePolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "SFLName02");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.deletePolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "SFLName02");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        assertEquals(1, result.getMessages().size());
+        result = apexModel.listPolicyStateFinalizerLogic("MyTestPolicy", null, "TestState1", "SFLName02");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateFinalizerLogic("MyTestPolicy", null, "TestState1", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(4, result.getMessages().size());
+        result = apexModel.deletePolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(4, result.getMessages().size());
+        result = apexModel.deletePolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateFinalizerLogic("MyTestPolicy", null, "TestState1", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "SFLName02",
+                "UNDEFINED", "Some Policy Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "SFLName03", "MVEL",
+                "Some Policy Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "SFLName04", "JAVA",
+                "Some Policy Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", "0.0.1", "TestState1", "SFLName05", "JYTHON",
+                "Some Policy Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", null, "TestState1", "SFLName06",
+                "JAVASCRIPT", "Some Policy Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicyStateFinalizerLogic("MyTestPolicy", null, "TestState1", "SFLName07", "JRUBY",
+                "Some Policy Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.createTask("TestTask0", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createTask("TestTask1", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createTask("TestTask2", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createTask("TestTask3", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createTask("TestTask4", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.createPolicyStateTaskRef(null, null, null, null, null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createPolicyStateTaskRef("MyTestPolicy", null, null, null, null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createPolicyStateTaskRef("MyTestPolicy", null, "SomeState", null, null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createPolicyStateTaskRef("MyTestPolicy", null, "SomeState", null, null, null, null,
+                "DummyOutput");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createPolicyStateTaskRef("MyTestPolicy", "1.2.3", "SomeState", null, null, null, null,
+                "DummyOutput");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createPolicyStateTaskRef("AnyOldPolicy", "1.2.3", "SomeState", null, null, null, null,
+                "DummyOutput");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createPolicyStateTaskRef("MyTestPolicy", "0.0.1", "TestState1", "SomeTaskLocalName", null,
+                null, null, "DummyOutput");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createPolicyStateTaskRef("MyTestPolicy", "0.0.1", "TestState1", "SomeTaskLocalName",
+                "SomeTask", "Zooby|", null, "DummyOutput");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createPolicyStateTaskRef("MyTestPolicy", "0.0.1", "TestState1", "SomeTaskLocalName",
+                "SomeTask", "0.0.1", null, "DummyOutput");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createPolicyStateTaskRef("MyTestPolicy", "0.0.1", "TestState1", "SomeTaskLocalName", "task",
+                "0.0.1", null, "DummyOutput");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createPolicyStateTaskRef("MyTestPolicy", "0.0.1", "TestState1", "SomeTaskLocalName", "task",
+                "0.0.1", "Some Policy Logic", "DummyOutput");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createPolicyStateTaskRef("MyTestPolicy", "0.0.1", "TestState1", "SomeTaskLocalName", "task",
+                "0.0.1", "DIRECT", "DummyOutput");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createPolicyStateTaskRef("MyTestPolicy", "0.0.1", "TestState1", "SomeTaskLocalName", "task",
+                "0.0.1", "LOGIC", "DummyOutput");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createPolicyStateTaskRef("MyTestPolicy", null, "TestState1", "SomeTaskLocalName", "task",
+                "0.0.1", "DIRECT", "SFLName07");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createPolicyStateTaskRef("MyTestPolicy", null, "TestState1", "SomeTaskLocalName", "task",
+                "0.0.1", "LOGIC", "SomeOutput");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createPolicyStateTaskRef("MyTestPolicy", null, "TestState1", "SomeTaskLocalName", "task",
+                "0.0.1", "DIRECT", "SomeOutput");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicyStateTaskRef("MyTestPolicy", null, "TestState1", "SomeTaskLocalName",
+                "NonExistantTask", "0.0.1", "DIRECT", "SomeOutput");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createPolicyStateTaskRef("MyTestPolicy", null, "TestState1", "SomeTaskLocalName", "task",
+                "0.0.1", "LOGIC", "SFLName07");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_EXISTS));
+        result = apexModel.createPolicyStateTaskRef("MyTestPolicy", null, "TestState1", "SomeTaskLocalName",
+                "TestTask0", "0.0.1", "LOGIC", "SFLName07");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicyStateTaskRef("MyTestPolicy", null, "TestState1", "SomeTaskLocalName",
+                "TestTask1", "0.0.1", "DIRECT", "SomeOtherOutput");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicyStateTaskRef("MyTestPolicy", null, "TestState1", "SomeTaskLocalName",
+                "TestTask2", "0.0.1", "LOGIC", "SFLName07");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicyStateTaskRef("MyTestPolicy", null, "TestState1", "SomeTaskLocalName",
+                "TestTask3", "0.0.1", "DIRECT", "SomeOtherOutput");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicyStateTaskRef("MyTestPolicy", null, "TestState1", null, "TestTask4", "0.0.1",
+                "LOGIC", "SFLName07");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicyStateTaskRef("MyTestPolicy", null, "TestState1", null, "TestTask4", "0.0.1",
+                "LOGIC", "SFLName07");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_EXISTS));
+        result = apexModel.deletePolicyStateTaskRef("MyTestPolicy", null, "TestState1", "TestTask4", "0.0.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicyStateTaskRef("MyTestPolicy", null, "TestState1", "SomeTaskLocalName",
+                "TestTask4", "0.0.1", "FUNKY", "SFLName07");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createPolicyStateTaskRef("MyTestPolicy", null, "TestState1", "SomeTaskLocalName",
+                "TestTask4", "0.0.1", "UNDEFINED", "SFLName07");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createPolicyStateTaskRef("MyTestPolicy", null, "TestState1", "SomeTaskLocalName",
+                "TestTask4", "0.0.1", "LOGIC", "SFLName07");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicyStateTaskRef("MyTestPolicy", null, "TestState1", null, "TestTask0", "0.0.1",
+                "LOGIC", "SFLName07");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_EXISTS));
+
+        result = apexModel.listPolicyStateTaskRef(null, null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.listPolicyStateTaskRef("MyTestPolicy", null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.listPolicyStateTaskRef("MyTestPolicy", "0.0.1", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.listPolicyStateTaskRef("MyTestPolicy", "0.0.2", "TestState1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateTaskRef("MyTestPolicy", null, "SomeState", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateTaskRef("MyTestPolicy", "0.0.1", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.listPolicyStateTaskRef("zooby", null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.listPolicyStateTaskRef("zooby", null, "looby", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateTaskRef("zooby", null, "TestState1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateTaskRef("MyTestPolicy", null, "looby", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateTaskRef("MyTestPolicy", "0.0.2", "TestState1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateTaskRef("MyTestPolicy", null, "TestState1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(12, result.getMessages().size());
+        result = apexModel.listPolicyStateTaskRef("MyTestPolicy", null, "TestState1", "SomeOldTask", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateTaskRef("MyTestPolicy", null, "TestState1", "task", "1.0.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        assertEquals(1, result.getMessages().size());
+        result = apexModel.listPolicyStateTaskRef("MyTestPolicy", null, "TestState1", "task", "0.0.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(2, result.getMessages().size());
+        result = apexModel.listPolicyStateTaskRef("MyTestPolicy", null, "TestState1", "task", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(2, result.getMessages().size());
+
+        result = apexModel.deletePolicyStateTaskRef(null, null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.deletePolicyStateTaskRef("MyTestPolicy", null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.deletePolicyStateTaskRef("MyTestPolicy", "0.0.1", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.deletePolicyStateTaskRef("MyTestPolicy", "0.0.2", "TestState1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deletePolicyStateTaskRef("MyTestPolicy", null, "SomeState", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deletePolicyStateTaskRef("MyTestPolicy", "0.0.1", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.deletePolicyStateTaskRef("zooby", null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.deletePolicyStateTaskRef("zooby", null, "looby", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deletePolicyStateTaskRef("zooby", null, "TestState1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deletePolicyStateTaskRef("MyTestPolicy", null, "looby", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deletePolicyStateTaskRef("MyTestPolicy", "0.0.2", "TestState1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deletePolicyStateTaskRef("MyTestPolicy", "0.0.2", "TestState1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deletePolicyStateTaskRef("MyTestPolicy", "0.0.1", "TestState1", "ADummyTask", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deletePolicyStateTaskRef("MyTestPolicy", "0.0.1", "TestState1", "task", "0.0.2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateTaskRef("MyTestPolicy", null, "TestState1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(12, result.getMessages().size());
+        result = apexModel.deletePolicyStateTaskRef("MyTestPolicy", null, "TestState1", "TestTask0", "0.0.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(1, result.getMessages().size());
+        result = apexModel.listPolicyStateTaskRef("MyTestPolicy", null, "TestState1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(10, result.getMessages().size());
+        result = apexModel.deletePolicyStateTaskRef("MyTestPolicy", null, "TestState1", "TestTask2", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(1, result.getMessages().size());
+        result = apexModel.listPolicyStateTaskRef("MyTestPolicy", null, "TestState1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(8, result.getMessages().size());
+        result = apexModel.deletePolicyStateTaskRef("MyTestPolicy", null, "TestState1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(4, result.getMessages().size());
+        result = apexModel.listPolicyStateTaskRef("MyTestPolicy", null, "TestState1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.createPolicyStateContextRef(null, null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createPolicyStateContextRef("MyTestPolicy", null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createPolicyStateContextRef("MyTestPolicy", null, "SomeState", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createPolicyStateContextRef("MyTestPolicy", null, "SomeState", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createPolicyStateContextRef("MyTestPolicy", "1.2.3", "SomeState", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createPolicyStateContextRef("AnyOldPolicy", "1.2.3", "SomeState", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "SomeTask", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "SomeTask", "Zooby|");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "SomeTask", "0.0.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "task", "0.0.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createPolicyStateContextRef("MyPolicy123", null, null, "AContextMap00", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createPolicyStateContextRef("MyPolicy123", null, "TestState1", "AContextMap00", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createPolicyStateContextRef("MyTestPolicy", "4.5.6", "TestState1", "AContextMap00", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createPolicyStateContextRef("MyTestPolicy", "0.1.4", "TestState1", "AContextMap00", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "AContextMap00", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "contextAlbum0", "");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "contextAlbum0", "0.0.2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.createPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "contextAlbum0", "0.0.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "contextAlbum0", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_EXISTS));
+        result = apexModel.createPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "contextAlbum0", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_EXISTS));
+        result = apexModel.createPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "contextAlbum1", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "contextAlbum0", "0.0.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_EXISTS));
+        result = apexModel.createPolicyStateContextRef("MyTestPolicy", null, "TestState1", "contextAlbum0", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_EXISTS));
+
+        result = apexModel.listPolicyStateContextRef(null, null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.listPolicyStateContextRef("MyTestPolicy", null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.listPolicyStateContextRef("MyTestPolicy", "0.0.1", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.listPolicyStateContextRef("MyTestPolicy", "0.0.2", "TestState1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateContextRef("MyTestPolicy", null, "SomeState", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateContextRef("MyTestPolicy", "0.0.1", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.listPolicyStateContextRef("zooby", null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.listPolicyStateContextRef("zooby", null, "looby", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateContextRef("zooby", null, "TestState1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateContextRef("MyTestPolicy", null, "looby", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateContextRef("MyTestPolicy", "0.0.2", "TestState1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateContextRef("MyTestPolicy", null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.listPolicyStateContextRef("MyTestPolicy", null, "TestState1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(2, result.getMessages().size());
+        result = apexModel.listPolicyStateContextRef("MyTestPolicy", "0.0.2", "TestState1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(2, result.getMessages().size());
+        result = apexModel.listPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "contextAlbum0", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(1, result.getMessages().size());
+        result = apexModel.listPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "contextAlbum0", "0.0.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(1, result.getMessages().size());
+        result = apexModel.listPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "contextAlbum0", "0.0.2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "AContextMap04", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "contextAlbum0", "0.0.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(1, result.getMessages().size());
+        result = apexModel.listPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "contextAlbum0", "1.0.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.deletePolicyStateContextRef(null, null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.deletePolicyStateContextRef("MyTestPolicy", null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.deletePolicyStateContextRef("MyTestPolicy", "0.0.1", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.deletePolicyStateContextRef("MyTestPolicy", "0.0.2", "TestState1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deletePolicyStateContextRef("MyTestPolicy", null, "SomeState", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deletePolicyStateContextRef("MyTestPolicy", "0.0.1", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.deletePolicyStateContextRef("zooby", null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.deletePolicyStateContextRef("zooby", null, "looby", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deletePolicyStateContextRef("zooby", null, "TestState1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deletePolicyStateContextRef("MyTestPolicy", null, "looby", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deletePolicyStateContextRef("MyTestPolicy", "0.0.2", "TestState1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deletePolicyStateContextRef("MyTestPolicy", "0.0.2", "TestState1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deletePolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "ADummyContextMap", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deletePolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "contextAlbum0", "0.0.2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listPolicyStateContextRef("MyTestPolicy", null, null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.deletePolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "AContextMap04", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deletePolicyStateContextRef("MyTestPolicy", null, "TestState1", "contextAlbum0", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.deletePolicyStateContextRef("MyTestPolicy", null, "TestState1", "contextAlbum0", "0.1.5");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deletePolicyStateContextRef("MyTestPolicy", null, "TestState1", "contextAlbum1", "0.0.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(1, result.getMessages().size());
+        result = apexModel.createPolicyStateContextRef("MyTestPolicy", "0.0.1", "TestState1", "contextAlbum0", "0.0.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.deletePolicyStateContextRef("MyTestPolicy", null, "TestState1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.deletePolicyStateContextRef("MyTestPolicy", null, "TestState1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        assertEquals(1, result.getMessages().size());
+        result = apexModel.listPolicyStateContextRef("MyTestPolicy", null, "TestState1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.deletePolicy(null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(3, result.getMessages().size());
+
+        result = apexModel.listPolicy(null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(0, result.getMessages().size());
+    }
+}
diff --git a/model/model-api/src/test/java/org/onap/policy/apex/model/modelapi/TestApexEditorAPITask.java b/model/model-api/src/test/java/org/onap/policy/apex/model/modelapi/TestApexEditorAPITask.java
new file mode 100644
index 0000000..e39da28
--- /dev/null
+++ b/model/model-api/src/test/java/org/onap/policy/apex/model/modelapi/TestApexEditorAPITask.java
@@ -0,0 +1,484 @@
+/*-
+ * ============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.model.modelapi;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+/**
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class TestApexEditorAPITask {
+    @Test
+    public void testTaskCRUD() {
+        final ApexModel apexModel = new ApexModelFactory().createApexModel(null, false);
+
+        ApexAPIResult result = apexModel.validateTask(null, null);
+        assertEquals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+        result = apexModel.validateTask("%%%$£", null);
+        assertEquals(ApexAPIResult.RESULT.FAILED, result.getResult());
+
+        result = apexModel.loadFromFile("src/test/resources/models/PolicyModel.json");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.createTask("@^^$^^$", "0.0.2", "1fa2e430-f2b2-11e6-bc64-92361f002700",
+                "A description of 002");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createTask("MyTask002", "0.0.2", "1fa2e430-f2b2-11e6-bc64-92361f002700",
+                "A description of 002");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createTask("MyTask002", "0.0.2", "1fa2e430-f2b2-11e6-bc64-92361f002700",
+                "A description of 002");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_EXISTS));
+        result = apexModel.createTask("MyTask012", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createTask("MyTask012", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_EXISTS));
+        result = apexModel.listTask(null, null);
+        result = apexModel.createTask("MyTask002", "0.0.2", "1fa2e430-f2b2-11e6-bc64-92361f002700",
+                "A description of 002");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_EXISTS));
+        result = apexModel.createTask("MyTask012", "0.1.2", "1fa2e430-f2b2-11e6-bc64-92361f002700",
+                "A description of 002");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.deleteTask("MyTask002", "0.0.2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createTask("MyTask002", "0.0.2", "1fa2e430-f2b2-11e6-bc64-92361f002700",
+                "A description of 002");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.validateTask(null, null);
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+
+        result = apexModel.updateTask("@$$$£", "0.0.2", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.updateTask("MyTask002", "0.0.2", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updateTask("MyTask002", "0.0.1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.updateTask("MyTask002", "0.0.2", "1fa2e430-f2b2-11e6-bc64-92361f002700",
+                "A description of 002");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updateTask("MyTask012", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updateTask("MyTask012", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updateTask("MyTask012", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updateTask("MyTask015", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.updateTask("MyTask014", "0.1.5", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.listTask("£@£@@£@£", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.listTask(null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listTask("MyTask012", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listTask("MyTask012", "0.0.2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listTask("MyTask012", "0.2.5");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listTask("MyTask014", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.deleteTask("@£££@", "0.1.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.deleteTask("MyTask012", "0.1.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deleteTask("MyTask012oooo", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.listTask("MyTask012", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertTrue(result.getMessages().size() == 2);
+
+        result = apexModel.deleteTask("MyTask012", "0.1.2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.listTask("MyTask012", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertTrue(result.getMessages().size() == 1);
+
+        result = apexModel.deleteTask("MyTask012", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.listTask("MyTask012", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.updateTaskLogic("MyTask002", null, "NewLogic00", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.createTaskLogic("MyTask123", null, "NewLogic00", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createTaskLogic("MyTask002", "4.5.6", "NewLogic00", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createTaskLogic("MyTask002", "0.1.4", "NewLogic00", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createTaskLogic("MyTask002", "0.0.2", "NewLogic00", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createTaskLogic("MyTask002", "0.0.2", "UNDEFINED", "Some Task Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createTaskLogic("MyTask002", "0.0.2", "MVEL", "Some Task Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_EXISTS));
+        result = apexModel.deleteTaskLogic("MyTask002", "0.0.2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createTaskLogic("MyTask002", "0.0.2", "JAVA", "Some Task Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createTaskLogic("MyTask002", "0.0.2", "JYTHON", "Some Task Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_EXISTS));
+        result = apexModel.deleteTaskLogic("MyTask002", "0.0.2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createTaskLogic("MyTask002", null, "JAVASCRIPT", "Some Task Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.deleteTaskLogic("MyTask002", "0.0.2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createTaskLogic("MyTask002", null, "JRUBY", "Some Task Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.updateTaskLogic("MyTask002", "0.0.2", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updateTaskLogic("MyTask002", "0.0.1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.updateTaskLogic("MyTask002", "0.0.2", "", "Some Other Task Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.updateTaskLogic("MyTask002", "0.0.2", "MVEL", "Some Other Task Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updateTaskLogic("MyTask012", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.updateTaskLogic("MyTask002", null, null, "Some Other Task Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updateTaskLogic("MyTask002", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.updateTaskLogic("MyTask015", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.updateTaskLogic("MyTask014", "0.1.5", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.listTaskLogic("MyTask002", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listTaskLogic("MyTask002", "0.0.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listTaskLogic("MyTask002", "0.0.2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listTaskLogic("MyTask002", "0.0.2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listTaskLogic("MyTask002", "0.0.2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listTaskLogic(null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+
+        result = apexModel.deleteTaskLogic("@£@£@£", "0.0.2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.deleteTaskLogic("NonExistantTask", "0.0.2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        assertEquals(1, apexModel.listTaskLogic("MyTask002", null).getMessages().size());
+        result = apexModel.deleteTaskLogic("MyTask002", "0.0.2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listTaskLogic("MyTask002", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.deleteTaskLogic("MyTask002", "0.0.2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        assertEquals(1, apexModel.listTaskLogic("MyTask002", null).getMessages().size());
+        result = apexModel.createTaskLogic("MyTask002", null, "JRUBY", "Some Task Logic");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listTaskLogic("MyTask002", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.deleteTaskLogic("MyTask002", "0.0.2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.deleteTaskLogic("MyTask002", "0.0.2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.createTaskInputField("MyTask123", null, "NewField00", null, null, false);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.createTaskInputField("MyTask002", "4.5.6", "NewField00", null, null, true);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.createTaskInputField("MyTask002", "0.1.4", "NewField00", null, null, false);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.createTaskInputField("MyTask002", "0.0.2", "NewField00", null, null, true);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+
+        result = apexModel.createTaskInputField("MyTask002", "0.0.2", "NewField00", "eventContextItem0", null, false);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createTaskInputField("MyTask002", "0.0.2", "NewField00", "eventContextItem0", null, true);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_EXISTS));
+        result = apexModel.createTaskInputField("MyTask002", "0.0.2", "NewField01", "eventContextItem0", "0.0.1",
+                false);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createTaskInputField("MyTask002", "0.0.2", "NewField02", "eventContextItem0", "0.0.2", true);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createTaskInputField("MyTask002", null, "NewField02", "eventContextItem0", null, false);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createTaskInputField("MyTask002", null, "NewField03", "eventContextItem0", null, true);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.listTaskInputField("@£$%", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.listTaskInputField("MyTask002", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listTaskInputField("MyTask002", "0.0.1", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listTaskInputField("MyTask002", "0.0.2", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listTaskInputField("MyTask002", "0.0.2", "NewField01");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listTaskInputField("MyTask002", "0.0.2", "NewField02");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listTaskInputField("MyTask002", "0.0.2", "NewField04");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.deleteTaskInputField("@£$%", "0.0.2", "NewField04");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.deleteTaskInputField("NonExistantTask", "0.0.2", "NewField04");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        assertEquals(4, apexModel.listTaskInputField("MyTask002", null, null).getMessages().size());
+        result = apexModel.deleteTaskInputField("MyTask002", "0.0.2", "NewField04");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        assertEquals(4, apexModel.listTaskInputField("MyTask002", null, null).getMessages().size());
+        result = apexModel.deleteTaskInputField("MyTask002", null, "NewField02");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(3, apexModel.listTaskInputField("MyTask002", null, null).getMessages().size());
+        result = apexModel.deleteTaskInputField("MyTask002", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listTaskInputField("MyTask002", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deleteTaskInputField("MyTask002", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.createTaskOutputField("MyTask123", null, "NewField00", null, null, false);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.createTaskOutputField("MyTask002", "4.5.6", "NewField00", null, null, false);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.createTaskOutputField("MyTask002", "0.1.4", "NewField00", null, null, false);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.createTaskOutputField("MyTask002", "0.0.2", "NewField00", null, null, false);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+
+        result = apexModel.createTaskOutputField("MyTask002", "0.0.2", "NewField00", "eventContextItem0", null, false);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createTaskOutputField("MyTask002", "0.0.2", "NewField00", "eventContextItem0", null, false);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_EXISTS));
+        result = apexModel.createTaskOutputField("MyTask002", "0.0.2", "NewField01", "eventContextItem0", "0.0.1",
+                false);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createTaskOutputField("MyTask002", "0.0.2", "NewField02", "eventContextItem0", "0.0.2",
+                false);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createTaskOutputField("MyTask002", null, "NewField02", "eventContextItem0", null, false);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createTaskOutputField("MyTask002", null, "NewField03", "eventContextItem0", null, false);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.listTaskOutputField("@£$%", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.listTaskOutputField("MyTask002", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listTaskOutputField("MyTask002", "0.0.1", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listTaskOutputField("MyTask002", "0.0.2", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listTaskOutputField("MyTask002", "0.0.2", "NewField01");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listTaskOutputField("MyTask002", "0.0.2", "NewField02");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listTaskOutputField("MyTask002", "0.0.2", "NewField04");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.deleteTaskOutputField("@£$%", "0.0.2", "NewField04");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.deleteTaskOutputField("NonExistantTask", "0.0.2", "NewField04");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        assertEquals(4, apexModel.listTaskOutputField("MyTask002", null, null).getMessages().size());
+        result = apexModel.deleteTaskOutputField("MyTask002", "0.0.2", "NewField04");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        assertEquals(4, apexModel.listTaskOutputField("MyTask002", null, null).getMessages().size());
+        result = apexModel.deleteTaskOutputField("MyTask002", null, "NewField02");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(3, apexModel.listTaskOutputField("MyTask002", null, null).getMessages().size());
+        result = apexModel.deleteTaskOutputField("MyTask002", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listTaskOutputField("MyTask002", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deleteTaskOutputField("MyTask002", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.createTaskParameter("MyTask123", null, "NewPar00", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.createTaskParameter("MyTask002", "4.5.6", "NewPar00", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.createTaskParameter("MyTask002", "0.1.4", "NewPar00", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.createTaskParameter("MyTask002", "0.0.2", "NewPar00", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+
+        result = apexModel.createTaskParameter("MyTask002", "0.0.2", "NewPar00", "eventContextItem0");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createTaskParameter("MyTask002", "0.0.2", "NewPar00", "eventContextItem0");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_EXISTS));
+        result = apexModel.createTaskParameter("MyTask002", "0.0.2", "NewPar01", "eventContextItem0");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createTaskParameter("MyTask002", "0.0.2", "NewPar02", "eventContextItem0");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createTaskParameter("MyTask002", "0.0.2", "NewPar02", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_EXISTS));
+        result = apexModel.createTaskParameter("MyTask002", "0.0.2", "NewPar03", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createTaskParameter("MyTask002", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createTaskParameter("MyTask002", null, null, "Default value");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+
+        result = apexModel.listTaskParameter("@£$%", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.listTaskParameter("MyTask002", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listTaskParameter("MyTask002", "0.0.3", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listTaskParameter("MyTask002", "0.0.2", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listTaskParameter("MyTask002", "0.0.2", "NewPar01");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listTaskParameter("MyTask002", "0.0.2", "NewPar02");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listTaskParameter("MyTask002", "0.0.2", "NewPar04");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.deleteTaskParameter("@£$%", "0.0.2", "NewPar04");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.deleteTaskParameter("NonExistantTask", "0.0.2", "NewPar04");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        assertEquals(3, apexModel.listTaskParameter("MyTask002", null, null).getMessages().size());
+        result = apexModel.deleteTaskParameter("MyTask002", "0.0.2", "NewPar04");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        assertEquals(3, apexModel.listTaskParameter("MyTask002", null, null).getMessages().size());
+        result = apexModel.deleteTaskParameter("MyTask002", null, "NewPar02");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(2, apexModel.listTaskParameter("MyTask002", null, null).getMessages().size());
+        result = apexModel.deleteTaskParameter("MyTask002", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.listTaskParameter("MyTask002", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deleteTaskParameter("MyTask002", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.createTaskContextRef("@£$$", null, "AContextMap00", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.createTaskContextRef("MyTask123", null, "AContextMap00", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createTaskContextRef("MyTask123", null, "AContextMap00", "0.0.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createTaskContextRef("MyTask123", null, "AContextMap00", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createTaskContextRef("MyTask002", "4.5.6", "AContextMap00", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createTaskContextRef("MyTask002", "0.1.4", "AContextMap00", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createTaskContextRef("MyTask002", "0.0.2", "AContextMap00", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createTaskContextRef("MyTask002", "0.0.2", "contextAlbum2", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.createTaskContextRef("MyTask002", "0.0.2", "contextAlbum0", "0.0.2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.createTaskContextRef("MyTask002", "0.0.2", "contextAlbum0", "0.0.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createTaskContextRef("MyTask002", "0.0.2", "contextAlbum0", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_EXISTS));
+        result = apexModel.createTaskContextRef("MyTask002", "0.0.2", "contextAlbum1", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        result = apexModel.createTaskContextRef("MyTask002", "0.0.2", "contextAlbum0", "0.0.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_EXISTS));
+        result = apexModel.createTaskContextRef("MyTask002", null, "contextAlbum0", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_EXISTS));
+
+        result = apexModel.listTaskContextRef("@£$%", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.listTaskContextRef("MyTask002", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(2, result.getMessages().size());
+        result = apexModel.listTaskContextRef("MyTask002", "0.0.1", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listTaskContextRef("MyTask002", "0.0.2", null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(2, result.getMessages().size());
+        result = apexModel.listTaskContextRef("MyTask002", "0.0.2", "contextAlbum0", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(1, result.getMessages().size());
+        result = apexModel.listTaskContextRef("MyTask002", "0.0.2", "contextAlbum0", "0.0.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(1, result.getMessages().size());
+        result = apexModel.listTaskContextRef("MyTask002", "0.0.2", "contextAlbum0", "0.0.2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listTaskContextRef("MyTask002", "0.0.2", "AContextMap04", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.listTaskContextRef("MyTask002", "0.0.2", "contextAlbum0", "0.0.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(1, result.getMessages().size());
+        result = apexModel.listTaskContextRef("MyTask002", "0.0.2", "contextAlbum1", "0.0.1");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(1, result.getMessages().size());
+        result = apexModel.listTaskContextRef("MyTask002", "0.0.2", "contextAlbum1", "0.0.2");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.deleteTaskContextRef("@£$%", "0.0.2", "AContextMap04", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        result = apexModel.deleteTaskContextRef("NonExistantTask", "0.0.2", "AContextMap04", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        assertEquals(2, apexModel.listTaskContextRef("MyTask002", null, null, null).getMessages().size());
+        result = apexModel.deleteTaskContextRef("MyTask002", "0.0.2", "AContextMap04", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deleteTaskContextRef("MyTask002", null, "contextAlbum0", "0.0.3");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deleteTaskContextRef("MyTask002", null, "contextAlbum0", "0.1.5");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+        result = apexModel.deleteTaskContextRef("MyTask002", null, "contextAlbum0", null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(1, result.getMessages().size());
+        result = apexModel.deleteTaskContextRef("MyTask002", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(1, result.getMessages().size());
+        result = apexModel.listTaskContextRef("MyTask002", null, null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST));
+
+        result = apexModel.deleteTask(null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(2, result.getMessages().size());
+
+        result = apexModel.listTask(null, null);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        assertEquals(0, result.getMessages().size());
+    }
+}
diff --git a/model/model-api/src/test/java/org/onap/policy/apex/model/modelapi/TestApexModelAPI.java b/model/model-api/src/test/java/org/onap/policy/apex/model/modelapi/TestApexModelAPI.java
new file mode 100644
index 0000000..52029d3
--- /dev/null
+++ b/model/model-api/src/test/java/org/onap/policy/apex/model/modelapi/TestApexModelAPI.java
@@ -0,0 +1,259 @@
+/*-
+ * ============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.model.modelapi;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.util.UUID;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.dao.DAOParameters;
+import org.onap.policy.apex.model.modelapi.impl.ApexModelImpl;
+import org.onap.policy.apex.model.utilities.TextFileUtils;
+
+/**
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class TestApexModelAPI {
+    private Connection connection;
+
+    @Before
+    public void setup() throws Exception {
+        Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
+        connection = DriverManager.getConnection("jdbc:derby:memory:apex_test;create=true");
+    }
+
+    @After
+    public void teardown() throws Exception {
+        connection.close();
+        new File("derby.log").delete();
+    }
+
+    @Test
+    public void testApexModelLoadFromFile() {
+        final ApexModel apexModel = new ApexModelFactory().createApexModel(null, false);
+
+        ApexAPIResult result = apexModel.loadFromFile("src/main/resources/models/PolicyModel.json");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+
+        result = apexModel.loadFromFile("src/test/resources/models/PolicyModel.json");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.deleteModel();
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.loadFromFile("src/test/resources/models/PolicyModel.xml");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.deleteModel();
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.loadFromFile("src/test/resources/models/PolicyModel.junk");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        assertTrue(result.getMessages().get(0).equals("format of input for Apex concept is neither JSON nor XML"));
+    }
+
+    @Test
+    public void testApexModelSaveToFile() throws IOException {
+        final ApexModel apexModel = new ApexModelFactory().createApexModel(null, false);
+
+        ApexAPIResult result = apexModel.loadFromFile("src/test/resources/models/PolicyModel.json");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        final File tempJsonModelFile = File.createTempFile("ApexModelTest", ".json");
+        result = apexModel.saveToFile(tempJsonModelFile.getCanonicalPath(), false);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        final ApexModel jsonApexModel = new ApexModelFactory().createApexModel(null, false);
+        result = jsonApexModel.loadFromFile(tempJsonModelFile.getCanonicalPath());
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        tempJsonModelFile.delete();
+
+        final File tempXMLModelFile = File.createTempFile("ApexModelTest", ".xml");
+        result = apexModel.saveToFile(tempXMLModelFile.getCanonicalPath(), true);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        final ApexModel xmlApexModel = new ApexModelFactory().createApexModel(null, false);
+        result = xmlApexModel.loadFromFile(tempXMLModelFile.getCanonicalPath());
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+        tempXMLModelFile.delete();
+    }
+
+    @Test
+    public void testApexModelDatabase() throws IOException {
+        final ApexModel apexModel = new ApexModelFactory().createApexModel(null, false);
+
+        ApexAPIResult result = apexModel.loadFromFile("src/test/resources/models/PolicyModel.json");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        final DAOParameters daoParameters = new DAOParameters();
+        daoParameters.setPluginClass("org.onap.policy.apex.model.basicmodel.dao.impl.DefaultApexDao");
+        daoParameters.setPersistenceUnit("DAOTest");
+
+        result = apexModel.saveToDatabase(daoParameters);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.deleteModel();
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.loadFromDatabase("PolicyModel", "0.0.1", daoParameters);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.deleteModel();
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.loadFromDatabase("PolicyModel", null, daoParameters);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.deleteModel();
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.loadFromDatabase("VPNPolicyModel", "0.0.1", daoParameters);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+    }
+
+    @Test
+    public void testApexModelURL() throws IOException {
+        ApexModel apexModel = new ApexModelFactory().createApexModel(null, false);
+
+        ApexAPIResult result = null;
+
+        try {
+            result = apexModel.readFromURL(null);
+            fail("expecting an IllegalArgumentException");
+        } catch (final Exception e) {
+            assertTrue(e instanceof IllegalArgumentException);
+        }
+
+        try {
+            result = apexModel.writeToURL(null, true);
+            fail("expecting an IllegalArgumentException");
+        } catch (final Exception e) {
+            assertTrue(e instanceof IllegalArgumentException);
+        }
+
+        result = apexModel.readFromURL("zooby/looby");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+
+        result = apexModel.writeToURL("zooby/looby", true);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+
+        result = apexModel.readFromURL("zooby://zooby/looby");
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+
+        result = apexModel.writeToURL("zooby://zooby/looby", false);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+
+        apexModel = new ApexModelFactory().createApexModel(null, false);
+
+        final File tempJsonModelFile = File.createTempFile("ApexModelTest", ".json");
+        result = apexModel.saveToFile(tempJsonModelFile.getCanonicalPath(), false);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        final String tempFileURLString = tempJsonModelFile.toURI().toString();
+        result = apexModel.readFromURL(tempFileURLString);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.SUCCESS));
+
+        result = apexModel.writeToURL(tempFileURLString, false);
+        assertTrue(result.getResult().equals(ApexAPIResult.RESULT.FAILED));
+        assertTrue(result.getMessages().get(0).equals("protocol doesn't support output"));
+
+        tempJsonModelFile.delete();
+    }
+
+    @Test
+    public void testApexModelMisc() throws IOException {
+        final ApexModelImpl apexModelImpl = (ApexModelImpl) new ApexModelFactory().createApexModel(null, false);
+
+        ApexAPIResult result = null;
+
+        result = apexModelImpl.getModelKey();
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+
+        result = apexModelImpl.listModel();
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+
+        result = apexModelImpl.createModel("ModelName", "0.0.1", null, null);
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+
+        result = apexModelImpl.updateModel("ModelName", "0.0.1", UUID.randomUUID().toString(), "Model Description");
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+
+        apexModelImpl.deleteModel();
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+
+        final String modelString = TextFileUtils.getTextFileAsString("src/test/resources/models/PolicyModel.json");
+        result = apexModelImpl.loadFromString(modelString);
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+
+        final File tempFile = File.createTempFile("ApexModel", "json");
+        tempFile.deleteOnExit();
+        TextFileUtils.putStringAsFile(modelString, tempFile);
+
+        apexModelImpl.deleteModel();
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+
+        result = apexModelImpl.loadFromFile(tempFile.getCanonicalPath());
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+
+        result = apexModelImpl.saveToFile(null, false);
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+
+        result = apexModelImpl.analyse();
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+
+        result = apexModelImpl.validate();
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+
+        result = apexModelImpl.compare(tempFile.getCanonicalPath(), true, true);
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+
+        result = apexModelImpl.compareWithString(modelString, true, true);
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+
+        result = apexModelImpl.split("policy");
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+
+        result = apexModelImpl.split(tempFile.getCanonicalPath(), "policy");
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+
+        result = apexModelImpl.merge(tempFile.getCanonicalPath(), true);
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+
+        result = apexModelImpl.mergeWithString(modelString, true);
+        System.err.println(result);
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+
+        assertNotEquals(0, apexModelImpl.hashCode());
+        assertNotNull(apexModelImpl.clone());
+        assertNotNull(apexModelImpl.build());
+    }
+}
diff --git a/model/model-api/src/test/java/org/onap/policy/apex/model/modelapi/TestModelFacade.java b/model/model-api/src/test/java/org/onap/policy/apex/model/modelapi/TestModelFacade.java
new file mode 100644
index 0000000..7f946f5
--- /dev/null
+++ b/model/model-api/src/test/java/org/onap/policy/apex/model/modelapi/TestModelFacade.java
@@ -0,0 +1,110 @@
+/*-
+ * ============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.model.modelapi;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.util.Properties;
+import java.util.UUID;
+
+import org.junit.Test;
+import org.onap.policy.apex.model.modelapi.impl.ModelFacade;
+
+public class TestModelFacade {
+
+    @Test
+    public void testModelFacade() {
+        try {
+            new ModelFacade(null, null, false);
+            fail("test should throw an exception here");
+        } catch (final Exception e) {
+            assertEquals("apexModel may not be null", e.getMessage());
+        }
+
+        final ApexModel apexModel = new ApexModelFactory().createApexModel(null, false);
+
+        try {
+            new ModelFacade(apexModel, null, false);
+            fail("test should throw an exception here");
+        } catch (final Exception e) {
+            assertEquals("apexProperties may not be null", e.getMessage());
+        }
+
+        final Properties modelProperties = new Properties();
+        final ModelFacade mf = new ModelFacade(apexModel, modelProperties, false);
+
+        ApexAPIResult result = mf.createModel(null, null, null, null);
+        assertEquals(ApexAPIResult.RESULT.FAILED, result.getResult());
+
+        result = mf.createModel("ModelName", null, null, null);
+        assertEquals(ApexAPIResult.RESULT.FAILED, result.getResult());
+
+        result = mf.createModel("ModelName", "0.0.1", null, null);
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+
+        modelProperties.setProperty("DEFAULT_CONCEPT_VERSION", "");
+        result = mf.createModel("ModelName", null, null, null);
+        assertEquals(ApexAPIResult.RESULT.FAILED, result.getResult());
+
+        modelProperties.setProperty("DEFAULT_CONCEPT_VERSION", "£$£$£$");
+        result = mf.createModel("ModelName", null, null, null);
+        assertEquals(ApexAPIResult.RESULT.FAILED, result.getResult());
+
+        modelProperties.setProperty("DEFAULT_CONCEPT_VERSION", "0.0.1");
+        result = mf.createModel("ModelName", null, null, null);
+        assertEquals(ApexAPIResult.RESULT.CONCEPT_EXISTS, result.getResult());
+        result = mf.deleteModel();
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+        result = mf.createModel("ModelName", null, null, null);
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+
+        result = mf.updateModel("ModelName", null, UUID.randomUUID().toString(), "New Description");
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+
+        result = mf.updateModel("ModelName", "0.0.1", UUID.randomUUID().toString(), "New Description");
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+
+        modelProperties.remove("DEFAULT_CONCEPT_VERSION");
+        result = mf.updateModel("ModelName", null, UUID.randomUUID().toString(), "New Description");
+        assertEquals(ApexAPIResult.RESULT.FAILED, result.getResult());
+
+        result = mf.updateModel(null, null, UUID.randomUUID().toString(), "New Description");
+        assertEquals(ApexAPIResult.RESULT.FAILED, result.getResult());
+
+        result = mf.deleteModel();
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+        result = mf.updateModel("name", "0.0.1", UUID.randomUUID().toString(), "New Description");
+        assertEquals(ApexAPIResult.RESULT.CONCEPT_DOES_NOT_EXIST, result.getResult());
+
+        result = mf.getModelKey();
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+
+        result = mf.listModel();
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+        assertEquals("AxPolicyModel:(AxPolicyModel:(key=AxArtifactKey:(n", result.getMessage().substring(0, 50));
+
+        result = mf.deleteModel();
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+        assertNotNull(mf);
+    }
+}
diff --git a/model/model-api/src/test/java/org/onap/policy/apex/model/modelapi/TestModelHandlerFacade.java b/model/model-api/src/test/java/org/onap/policy/apex/model/modelapi/TestModelHandlerFacade.java
new file mode 100644
index 0000000..f13b8df
--- /dev/null
+++ b/model/model-api/src/test/java/org/onap/policy/apex/model/modelapi/TestModelHandlerFacade.java
@@ -0,0 +1,147 @@
+/*-
+ * ============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.model.modelapi;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Properties;
+
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.dao.DAOParameters;
+import org.onap.policy.apex.model.modelapi.impl.ModelHandlerFacade;
+import org.onap.policy.apex.model.utilities.TextFileUtils;
+
+/**
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class TestModelHandlerFacade {
+
+    @Test
+    public void testModelHandlerFacade() throws IOException {
+        try {
+            new ModelHandlerFacade(null, null, false);
+            fail("test should throw an exception here");
+        } catch (final Exception e) {
+            assertEquals("apexModel may not be null", e.getMessage());
+        }
+
+        final ApexModel apexModel = new ApexModelFactory().createApexModel(null, false);
+
+        try {
+            new ModelHandlerFacade(apexModel, null, false);
+            fail("test should throw an exception here");
+        } catch (final Exception e) {
+            assertEquals("apexProperties may not be null", e.getMessage());
+        }
+
+        final Properties modelProperties = new Properties();
+        final ModelHandlerFacade mhf = new ModelHandlerFacade(apexModel, modelProperties, false);
+        assertNotNull(mhf);
+
+        ApexAPIResult result = mhf.loadFromFile("src/test/resources/models/PolicyModel.json");
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+
+        result = mhf.loadFromFile("src/test/resources/models/PolicyModel.json");
+        assertEquals(ApexAPIResult.RESULT.CONCEPT_EXISTS, result.getResult());
+
+        final String modelString = TextFileUtils.getTextFileAsString("src/test/resources/models/PolicyModel.json");
+
+        result = apexModel.deleteModel();
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+
+        result = mhf.loadFromString(modelString);
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+
+        result = mhf.loadFromString(modelString);
+        assertEquals(ApexAPIResult.RESULT.CONCEPT_EXISTS, result.getResult());
+
+        final DAOParameters daoParameters = new DAOParameters();
+        result = mhf.loadFromDatabase("SomeModel", null, daoParameters);
+        assertEquals(ApexAPIResult.RESULT.CONCEPT_EXISTS, result.getResult());
+
+        result = apexModel.deleteModel();
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+
+        result = mhf.loadFromDatabase("SomeModel", null, daoParameters);
+        assertEquals(ApexAPIResult.RESULT.FAILED, result.getResult());
+
+        result = mhf.saveToDatabase(daoParameters);
+        assertEquals(ApexAPIResult.RESULT.FAILED, result.getResult());
+
+        result = mhf.readFromURL("blah://somewhere/over/the/rainbow");
+        assertEquals(ApexAPIResult.RESULT.FAILED, result.getResult());
+
+        result = mhf.loadFromString(modelString);
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+
+        result = mhf.readFromURL("http://somewhere/over/the/rainbow");
+        assertEquals(ApexAPIResult.RESULT.CONCEPT_EXISTS, result.getResult());
+
+        final File tempFile = File.createTempFile("ApexModel", "json");
+        tempFile.deleteOnExit();
+
+        result = mhf.writeToURL("File:///" + tempFile.getCanonicalPath(), false);
+        assertEquals(ApexAPIResult.RESULT.FAILED, result.getResult());
+
+        result = mhf.validate();
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+
+        result = apexModel.deleteModel();
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+        result = mhf.validate();
+        assertEquals(ApexAPIResult.RESULT.FAILED, result.getResult());
+
+        result = mhf.compare("src/test/resources/models/NonExistant.json", true, true);
+        assertEquals(ApexAPIResult.RESULT.FAILED, result.getResult());
+
+        result = mhf.compareWithString("zooby", true, true);
+        assertEquals(ApexAPIResult.RESULT.FAILED, result.getResult());
+
+        result = mhf.split("FailSplit", "NonExistantPolicy");
+        assertEquals(ApexAPIResult.RESULT.FAILED, result.getResult());
+
+        result = mhf.split("NonExistantPolicy");
+        assertEquals(ApexAPIResult.RESULT.FAILED, result.getResult());
+
+        result = mhf.merge("src/test/resources/models/NonExistant.json", false);
+        assertEquals(ApexAPIResult.RESULT.FAILED, result.getResult());
+
+        result = apexModel.deleteModel();
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+        result = mhf.merge("src/test/resources/models/PolicyModel.json", false);
+        assertEquals(ApexAPIResult.RESULT.FAILED, result.getResult());
+
+        result = mhf.loadFromFile("src/test/resources/models/PolicyModel.json");
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+
+        result = mhf.mergeWithString("@£@$@£", true);
+        assertEquals(ApexAPIResult.RESULT.FAILED, result.getResult());
+
+        result = apexModel.deleteModel();
+        assertEquals(ApexAPIResult.RESULT.SUCCESS, result.getResult());
+        result = mhf.mergeWithString(modelString, false);
+        assertEquals(ApexAPIResult.RESULT.FAILED, result.getResult());
+    }
+}
diff --git a/model/model-api/src/test/resources/META-INF/persistence.xml b/model/model-api/src/test/resources/META-INF/persistence.xml
new file mode 100644
index 0000000..3db7417
--- /dev/null
+++ b/model/model-api/src/test/resources/META-INF/persistence.xml
@@ -0,0 +1,69 @@
+<?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=========================================================
+-->
+
+<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
+    <persistence-unit name="DAOTest" transaction-type="RESOURCE_LOCAL">
+        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
+
+        <class>org.onap.policy.apex.model.basicmodel.dao.converters.CDATAConditioner</class>
+        <class>org.onap.policy.apex.model.basicmodel.dao.converters.UUID2String</class>
+        <class>org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey</class>
+        <class>org.onap.policy.apex.model.basicmodel.concepts.AxConcept</class>
+        <class>org.onap.policy.apex.model.basicmodel.concepts.AxKeyInfo</class>
+        <class>org.onap.policy.apex.model.basicmodel.concepts.AxKeyInformation</class>
+        <class>org.onap.policy.apex.model.basicmodel.concepts.AxModel</class>
+        <class>org.onap.policy.apex.model.basicmodel.concepts.TestEntity</class>
+        <class>org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema</class>
+        <class>org.onap.policy.apex.model.contextmodel.concepts.AxContextSchemas</class>
+        <class>org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum</class>
+        <class>org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbums</class>
+        <class>org.onap.policy.apex.model.contextmodel.concepts.AxContextModel</class>
+        <class>org.onap.policy.apex.model.eventmodel.concepts.AxField</class>
+        <class>org.onap.policy.apex.model.eventmodel.concepts.AxInputField</class>
+        <class>org.onap.policy.apex.model.eventmodel.concepts.AxOutputField</class>
+        <class>org.onap.policy.apex.model.eventmodel.concepts.AxEvent</class>
+        <class>org.onap.policy.apex.model.eventmodel.concepts.AxEvents</class>
+        <class>org.onap.policy.apex.model.eventmodel.concepts.AxEventModel</class>
+        <class>org.onap.policy.apex.model.policymodel.concepts.AxLogic</class>
+        <class>org.onap.policy.apex.model.policymodel.concepts.AxTaskParameter</class>
+        <class>org.onap.policy.apex.model.policymodel.concepts.AxTaskLogic</class>
+        <class>org.onap.policy.apex.model.policymodel.concepts.AxTask</class>
+        <class>org.onap.policy.apex.model.policymodel.concepts.AxTasks</class>
+        <class>org.onap.policy.apex.model.policymodel.concepts.AxTaskSelectionLogic</class>
+        <class>org.onap.policy.apex.model.policymodel.concepts.AxStateFinalizerLogic</class>
+        <class>org.onap.policy.apex.model.policymodel.concepts.AxStateOutput</class>
+        <class>org.onap.policy.apex.model.policymodel.concepts.AxStateTaskReference</class>
+        <class>org.onap.policy.apex.model.policymodel.concepts.AxState</class>
+        <class>org.onap.policy.apex.model.policymodel.concepts.AxPolicy</class>
+        <class>org.onap.policy.apex.model.policymodel.concepts.AxPolicies</class>
+        <class>org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel</class>
+
+        <properties>
+            <property name="javax.persistence.jdbc.url" value="jdbc:derby:memory:apex_test" />
+            <property name="javax.persistence.target-database" value="Derby" />
+            <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" />
+
+            <property name="eclipselink.ddl-generation" value="create-tables" />
+            <property name="eclipselink.ddl-generation.output-mode" value="database" />
+            <property name="eclipselink.logging.level" value="INFO" />
+        </properties>
+    </persistence-unit>
+</persistence>
diff --git a/model/model-api/src/test/resources/logback-test.xml b/model/model-api/src/test/resources/logback-test.xml
new file mode 100644
index 0000000..114b39c
--- /dev/null
+++ b/model/model-api/src/test/resources/logback-test.xml
@@ -0,0 +1,74 @@
+<?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="INFO">
+        <appender-ref ref="STDOUT" />
+    </root>
+
+    <logger name="org.infinispan" level="INFO" additivity="false">
+        <appender-ref ref="STDOUT" />
+    </logger>
+
+    <logger name="org.apache.zookeeper.ClientCnxn" level="OFF" additivity="false">
+        <appender-ref ref="STDOUT" />
+    </logger>
+
+    <logger name="org.onap.policy.apex.core" level="INFO" 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="TRACE" additivity="false">
+        <appender-ref ref="CTXT_FILE" />
+    </logger>
+
+    <logger name="org.onap.policy.apex.core.context" level="INFO" additivity="false">
+        <appender-ref ref="STDOUT" />
+    </logger>
+</configuration>
diff --git a/model/model-api/src/test/resources/models/PolicyModel.json b/model/model-api/src/test/resources/models/PolicyModel.json
new file mode 100644
index 0000000..81c2226
--- /dev/null
+++ b/model/model-api/src/test/resources/models/PolicyModel.json
@@ -0,0 +1,708 @@
+{
+   "apexPolicyModel" : {
+      "key" : {
+         "name" : "PolicyModel",
+         "version" : "0.0.1"
+      },
+      "keyInformation" : {
+         "key" : {
+            "name" : "KeyInfoMapKey",
+            "version" : "0.0.1"
+         },
+         "keyInfoMap" : {
+            "entry" : [ {
+               "key" : {
+                  "name" : "ContextSchemas",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "ContextSchemas",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "0ce9168c-e6df-414f-9646-6da464b6e000",
+                  "description" : "Generated description for concept referred to by key \"ContextSchemas:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "KeyInfoMapKey",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "KeyInfoMapKey",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "0ce9168c-e6df-414f-9646-6da464b6e001",
+                  "description" : "Generated description for concept referred to by key \"KeyInfoMapKey:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "MapType",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "MapType",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "0ce9168c-e6df-414f-9646-6da464b6e002",
+                  "description" : "Generated description for concept referred to by key \"MapType:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "PolicyModel",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "PolicyModel",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "0ce9168c-e6df-414f-9646-6da464b6e003",
+                  "description" : "Generated description for concept referred to by key \"PolicyModel:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "StringType",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "StringType",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "0ce9168c-e6df-414f-9646-6da464b6e004",
+                  "description" : "Generated description for concept referred to by key \"StringType:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "context",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "context",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "0ce9168c-e6df-414f-9646-6da464b6e005",
+                  "description" : "Generated description for concept referred to by key \"context:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "contextAlbum0",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "contextAlbum0",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "0ce9168c-e6df-414f-9646-6da464b6e006",
+                  "description" : "Generated description for concept referred to by key \"contextAlbum0:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "contextAlbum1",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "contextAlbum1",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "0ce9168c-e6df-414f-9646-6da464b6e007",
+                  "description" : "Generated description for concept referred to by key \"contextAlbum1:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "eventContextItem0",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "eventContextItem0",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "0ce9168c-e6df-414f-9646-6da464b6e008",
+                  "description" : "Generated description for concept referred to by key \"eventContextItem0:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "eventContextItem1",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "eventContextItem1",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "0ce9168c-e6df-414f-9646-6da464b6e009",
+                  "description" : "Generated description for concept referred to by key \"eventContextItem1:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "events",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "events",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "0ce9168c-e6df-414f-9646-6da464b6e010",
+                  "description" : "Generated description for concept referred to by key \"events:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "inEvent",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "inEvent",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "0ce9168c-e6df-414f-9646-6da464b6e011",
+                  "description" : "Generated description for concept referred to by key \"inEvent:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "outEvent0",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "outEvent0",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "0ce9168c-e6df-414f-9646-6da464b6e012",
+                  "description" : "Generated description for concept referred to by key \"outEvent0:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "outEvent1",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "outEvent1",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "0ce9168c-e6df-414f-9646-6da464b6e013",
+                  "description" : "Generated description for concept referred to by key \"outEvent1:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "policies",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "policies",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "0ce9168c-e6df-414f-9646-6da464b6e014",
+                  "description" : "Generated description for concept referred to by key \"policies:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "policy",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "policy",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "0ce9168c-e6df-414f-9646-6da464b6e015",
+                  "description" : "Generated description for concept referred to by key \"policy:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "task",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "task",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "0ce9168c-e6df-414f-9646-6da464b6e016",
+                  "description" : "Generated description for concept referred to by key \"task:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "tasks",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "tasks",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "0ce9168c-e6df-414f-9646-6da464b6e017",
+                  "description" : "Generated description for concept referred to by key \"tasks:0.0.1\""
+               }
+            } ]
+         }
+      },
+      "policies" : {
+         "key" : {
+            "name" : "policies",
+            "version" : "0.0.1"
+         },
+         "policyMap" : {
+            "entry" : [ {
+               "key" : {
+                  "name" : "policy",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "policyKey" : {
+                     "name" : "policy",
+                     "version" : "0.0.1"
+                  },
+                  "template" : "FREEFORM",
+                  "state" : {
+                     "entry" : [ {
+                        "key" : "state",
+                        "value" : {
+                           "stateKey" : {
+                              "parentKeyName" : "policy",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "state"
+                           },
+                           "trigger" : {
+                              "name" : "inEvent",
+                              "version" : "0.0.1"
+                           },
+                           "stateOutputs" : {
+                              "entry" : [ {
+                                 "key" : "stateOutput0",
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "policy",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "state",
+                                       "localName" : "stateOutput0"
+                                    },
+                                    "outgoingEvent" : {
+                                       "name" : "outEvent0",
+                                       "version" : "0.0.1"
+                                    },
+                                    "nextState" : {
+                                       "parentKeyName" : "NULL",
+                                       "parentKeyVersion" : "0.0.0",
+                                       "parentLocalName" : "NULL",
+                                       "localName" : "NULL"
+                                    }
+                                 }
+                              } ]
+                           },
+                           "contextAlbumReference" : [ {
+                              "name" : "contextAlbum0",
+                              "version" : "0.0.1"
+                           }, {
+                              "name" : "contextAlbum1",
+                              "version" : "0.0.1"
+                           } ],
+                           "taskSelectionLogic" : {
+                              "key" : "taskSelectionLogic",
+                              "logicFlavour" : "MVEL",
+                              "logic" : "Some TS logic"
+                           },
+                           "stateFinalizerLogicMap" : {
+                              "entry" : [ ]
+                           },
+                           "defaultTask" : {
+                              "name" : "task",
+                              "version" : "0.0.1"
+                           },
+                           "taskReferences" : {
+                              "entry" : [ {
+                                 "key" : {
+                                    "name" : "task",
+                                    "version" : "0.0.1"
+                                 },
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "policy",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "state",
+                                       "localName" : "task"
+                                    },
+                                    "outputType" : "DIRECT",
+                                    "output" : {
+                                       "parentKeyName" : "policy",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "state",
+                                       "localName" : "stateOutput0"
+                                    }
+                                 }
+                              } ]
+                           }
+                        }
+                     } ]
+                  },
+                  "firstState" : "state"
+               }
+            } ]
+         }
+      },
+      "tasks" : {
+         "key" : {
+            "name" : "tasks",
+            "version" : "0.0.1"
+         },
+         "taskMap" : {
+            "entry" : [ {
+               "key" : {
+                  "name" : "task",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "task",
+                     "version" : "0.0.1"
+                  },
+                  "inputFields" : {
+                     "entry" : [ {
+                        "key" : "IEPAR0",
+                        "value" : {
+                           "key" : "IEPAR0",
+                           "fieldSchemaKey" : {
+                              "name" : "eventContextItem0",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "IEPAR1",
+                        "value" : {
+                           "key" : "IEPAR1",
+                           "fieldSchemaKey" : {
+                              "name" : "eventContextItem1",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  },
+                  "outputFields" : {
+                     "entry" : [ {
+                        "key" : "OE0PAR0",
+                        "value" : {
+                           "key" : "OE0PAR0",
+                           "fieldSchemaKey" : {
+                              "name" : "eventContextItem0",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "OE0PAR1",
+                        "value" : {
+                           "key" : "OE0PAR1",
+                           "fieldSchemaKey" : {
+                              "name" : "eventContextItem1",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "OE1PAR0",
+                        "value" : {
+                           "key" : "OE1PAR0",
+                           "fieldSchemaKey" : {
+                              "name" : "eventContextItem0",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "OE1PAR1",
+                        "value" : {
+                           "key" : "OE1PAR1",
+                           "fieldSchemaKey" : {
+                              "name" : "eventContextItem1",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  },
+                  "taskParameters" : {
+                     "entry" : [ {
+                        "key" : "taskParameter0",
+                        "value" : {
+                           "key" : {
+                              "parentKeyName" : "task",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "taskParameter0"
+                           },
+                           "defaultValue" : "Task parameter 0 value"
+                        }
+                     }, {
+                        "key" : "taskParameter1",
+                        "value" : {
+                           "key" : {
+                              "parentKeyName" : "task",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "taskParameter1"
+                           },
+                           "defaultValue" : "Task parameter 1 value"
+                        }
+                     } ]
+                  },
+                  "contextAlbumReference" : [ {
+                     "name" : "contextAlbum0",
+                     "version" : "0.0.1"
+                  }, {
+                     "name" : "contextAlbum1",
+                     "version" : "0.0.1"
+                  } ],
+                  "taskLogic" : {
+                     "key" : "taskLogic",
+                     "logicFlavour" : "MVEL",
+                     "logic" : "Some task logic"
+                  }
+               }
+            } ]
+         }
+      },
+      "events" : {
+         "key" : {
+            "name" : "events",
+            "version" : "0.0.1"
+         },
+         "eventMap" : {
+            "entry" : [ {
+               "key" : {
+                  "name" : "inEvent",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "inEvent",
+                     "version" : "0.0.1"
+                  },
+                  "nameSpace" : "org.onap.policy.apex.model.policymodel.events",
+                  "source" : "Source",
+                  "target" : "Target",
+                  "parameter" : {
+                     "entry" : [ {
+                        "key" : "IEPAR0",
+                        "value" : {
+                           "key" : "IEPAR0",
+                           "fieldSchemaKey" : {
+                              "name" : "eventContextItem0",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "IEPAR1",
+                        "value" : {
+                           "key" : "IEPAR1",
+                           "fieldSchemaKey" : {
+                              "name" : "eventContextItem1",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  }
+               }
+            }, {
+               "key" : {
+                  "name" : "outEvent0",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "outEvent0",
+                     "version" : "0.0.1"
+                  },
+                  "nameSpace" : "org.onap.policy.apex.model.policymodel.events",
+                  "source" : "Source",
+                  "target" : "Target",
+                  "parameter" : {
+                     "entry" : [ {
+                        "key" : "OE0PAR0",
+                        "value" : {
+                           "key" : "OE0PAR0",
+                           "fieldSchemaKey" : {
+                              "name" : "eventContextItem0",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "OE0PAR1",
+                        "value" : {
+                           "key" : "OE0PAR1",
+                           "fieldSchemaKey" : {
+                              "name" : "eventContextItem1",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "OE1PAR0",
+                        "value" : {
+                           "key" : "OE1PAR0",
+                           "fieldSchemaKey" : {
+                              "name" : "eventContextItem0",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "OE1PAR1",
+                        "value" : {
+                           "key" : "OE1PAR1",
+                           "fieldSchemaKey" : {
+                              "name" : "eventContextItem1",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  }
+               }
+            }, {
+               "key" : {
+                  "name" : "outEvent1",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "outEvent1",
+                     "version" : "0.0.1"
+                  },
+                  "nameSpace" : "org.onap.policy.apex.model.policymodel.events",
+                  "source" : "Source",
+                  "target" : "Target",
+                  "parameter" : {
+                     "entry" : [ {
+                        "key" : "OE1PAR0",
+                        "value" : {
+                           "key" : "OE1PAR0",
+                           "fieldSchemaKey" : {
+                              "name" : "eventContextItem0",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "OE1PAR1",
+                        "value" : {
+                           "key" : "OE1PAR1",
+                           "fieldSchemaKey" : {
+                              "name" : "eventContextItem1",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  }
+               }
+            } ]
+         }
+      },
+      "albums" : {
+         "key" : {
+            "name" : "context",
+            "version" : "0.0.1"
+         },
+         "albums" : {
+            "entry" : [ {
+               "key" : {
+                  "name" : "contextAlbum0",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "contextAlbum0",
+                     "version" : "0.0.1"
+                  },
+                  "scope" : "APPLICATION",
+                  "isWritable" : true,
+                  "itemSchema" : {
+                     "name" : "MapType",
+                     "version" : "0.0.1"
+                  }
+               }
+            }, {
+               "key" : {
+                  "name" : "contextAlbum1",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "contextAlbum1",
+                     "version" : "0.0.1"
+                  },
+                  "scope" : "GLOBAL",
+                  "isWritable" : false,
+                  "itemSchema" : {
+                     "name" : "StringType",
+                     "version" : "0.0.1"
+                  }
+               }
+            } ]
+         }
+      },
+      "schemas" : {
+         "key" : {
+            "name" : "ContextSchemas",
+            "version" : "0.0.1"
+         },
+         "schemas" : {
+            "entry" : [ {
+               "key" : {
+                  "name" : "MapType",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "MapType",
+                     "version" : "0.0.1"
+                  },
+                  "schemaFlavour" : "Java",
+                  "schemaDefinition" : "org.onap.policy.apex.model.policymodel.concepts.TestContextItem00A"
+               }
+            }, {
+               "key" : {
+                  "name" : "StringType",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "StringType",
+                     "version" : "0.0.1"
+                  },
+                  "schemaFlavour" : "Java",
+                  "schemaDefinition" : "org.onap.policy.apex.model.policymodel.concepts.TestContextItem000"
+               }
+            }, {
+               "key" : {
+                  "name" : "eventContextItem0",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "eventContextItem0",
+                     "version" : "0.0.1"
+                  },
+                  "schemaFlavour" : "Java",
+                  "schemaDefinition" : "java.lang.String"
+               }
+            }, {
+               "key" : {
+                  "name" : "eventContextItem1",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "eventContextItem1",
+                     "version" : "0.0.1"
+                  },
+                  "schemaFlavour" : "Java",
+                  "schemaDefinition" : "java.lang.Long"
+               }
+            } ]
+         }
+      }
+   }
+}
\ No newline at end of file
diff --git a/model/model-api/src/test/resources/models/PolicyModel.junk b/model/model-api/src/test/resources/models/PolicyModel.junk
new file mode 100644
index 0000000..613a36a
--- /dev/null
+++ b/model/model-api/src/test/resources/models/PolicyModel.junk
@@ -0,0 +1,9 @@
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse cursus suscipit faucibus. Pellentesque sagittis, erat placerat ultricies maximus, erat nulla efficitur ex, quis hendrerit tellus urna quis libero. Nullam vitae nisl ut nisl condimentum suscipit. Aenean sagittis condimentum nisi quis condimentum. Suspendisse potenti. Aliquam eget purus a risus viverra volutpat eu eu neque. Phasellus in libero id turpis lobortis malesuada. Praesent dignissim tellus imperdiet faucibus interdum. Donec volutpat, eros non lobortis consectetur, felis arcu consequat purus, a pharetra velit nisi at ante. Etiam ut sem imperdiet justo aliquet tempus at ornare quam.
+
+Integer sed maximus tellus. Nulla venenatis congue massa nec vestibulum. Duis ultrices quis neque ultrices semper. Morbi rhoncus gravida nibh, ut consequat ex. Proin eget ex vel lectus luctus varius. Integer nec consectetur ante. Cras ac aliquam nibh, in fermentum metus. Praesent nec ipsum tristique, ultrices arcu vel, bibendum libero. Curabitur ac odio eget felis blandit accumsan viverra vitae nibh. Integer efficitur eros lectus, et convallis elit consectetur nec. Vivamus tellus sem, vestibulum ut faucibus ut, maximus nec nulla. Donec ex eros, tempus ac justo at, posuere finibus purus. Pellentesque lacinia eu eros nec dignissim. Vestibulum tempus lectus in placerat imperdiet. Sed a diam vitae lorem gravida commodo.
+
+Sed at dolor felis. Ut at luctus libero. Ut faucibus elementum sem. Praesent aliquet tempus magna, eget bibendum nisi ultricies eu. Aenean dictum libero dui, et finibus metus consequat sed. Nullam lobortis diam ut sem imperdiet, nec posuere mauris aliquet. Etiam nec laoreet leo. Vestibulum nec turpis ante. Vivamus imperdiet commodo velit in ultricies. Maecenas facilisis maximus odio vel vestibulum.
+
+Aenean dapibus mi eget eros sodales rhoncus. Mauris dolor mi, feugiat quis egestas id, vestibulum at augue. Vivamus sit amet enim metus. Donec nec ultricies felis. Phasellus aliquam urna lectus, mollis rutrum libero ornare nec. Quisque dictum ante ac dapibus placerat. Ut euismod euismod elit eget commodo. Aenean vestibulum tempus elit quis vestibulum. Integer dapibus ultricies bibendum. Vivamus iaculis egestas magna, a ornare lacus eleifend eu. Fusce non massa ut sapien volutpat molestie vel sit amet sapien. Phasellus hendrerit felis magna, quis pharetra dui finibus sed. Praesent quis accumsan purus, hendrerit viverra felis. Pellentesque semper pretium nisl, in auctor enim interdum ut. Nullam placerat erat vel lacus vestibulum vehicula. Morbi at augue in enim luctus feugiat.
+
+Nunc aliquam auctor turpis id pretium. Donec placerat egestas tortor quis blandit. Curabitur sagittis elit eu varius gravida. Fusce eget diam eu sapien convallis pellentesque. Donec ultrices odio id leo pellentesque, eget tempus erat efficitur. Pellentesque ac ultricies purus, ut condimentum libero. Pellentesque pulvinar urna vel sollicitudin commodo. Sed tincidunt sed nulla sed auctor. 
\ No newline at end of file
diff --git a/model/model-api/src/test/resources/models/PolicyModel.xml b/model/model-api/src/test/resources/models/PolicyModel.xml
new file mode 100644
index 0000000..a89f73d
--- /dev/null
+++ b/model/model-api/src/test/resources/models/PolicyModel.xml
@@ -0,0 +1,759 @@
+<?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=========================================================
+-->
+
+<apexPolicyModel xmlns="http://www.onap.org/policy/apex-pdp">
+    <key>
+        <name>PolicyModel</name>
+        <version>0.0.1</version>
+    </key>
+    <keyInformation>
+        <key>
+            <name>KeyInfoMapKey</name>
+            <version>0.0.1</version>
+        </key>
+        <keyInfoMap>
+            <entry>
+                <key>
+                    <name>ContextSchemas</name>
+                    <version>0.0.1</version>
+                </key>
+                <value>
+                    <key>
+                        <name>ContextSchemas</name>
+                        <version>0.0.1</version>
+                    </key>
+                    <UUID>0ce9168c-e6df-414f-9646-6da464b6e000</UUID>
+                    <description><![CDATA[Generated description for concept referred to by key "ContextSchemas:0.0.1"]]></description>
+                </value>
+            </entry>
+            <entry>
+                <key>
+                    <name>KeyInfoMapKey</name>
+                    <version>0.0.1</version>
+                </key>
+                <value>
+                    <key>
+                        <name>KeyInfoMapKey</name>
+                        <version>0.0.1</version>
+                    </key>
+                    <UUID>0ce9168c-e6df-414f-9646-6da464b6e001</UUID>
+                    <description><![CDATA[Generated description for concept referred to by key "KeyInfoMapKey:0.0.1"]]></description>
+                </value>
+            </entry>
+            <entry>
+                <key>
+                    <name>MapType</name>
+                    <version>0.0.1</version>
+                </key>
+                <value>
+                    <key>
+                        <name>MapType</name>
+                        <version>0.0.1</version>
+                    </key>
+                    <UUID>0ce9168c-e6df-414f-9646-6da464b6e002</UUID>
+                    <description><![CDATA[Generated description for concept referred to by key "MapType:0.0.1"]]></description>
+                </value>
+            </entry>
+            <entry>
+                <key>
+                    <name>PolicyModel</name>
+                    <version>0.0.1</version>
+                </key>
+                <value>
+                    <key>
+                        <name>PolicyModel</name>
+                        <version>0.0.1</version>
+                    </key>
+                    <UUID>0ce9168c-e6df-414f-9646-6da464b6e003</UUID>
+                    <description><![CDATA[Generated description for concept referred to by key "PolicyModel:0.0.1"]]></description>
+                </value>
+            </entry>
+            <entry>
+                <key>
+                    <name>StringType</name>
+                    <version>0.0.1</version>
+                </key>
+                <value>
+                    <key>
+                        <name>StringType</name>
+                        <version>0.0.1</version>
+                    </key>
+                    <UUID>0ce9168c-e6df-414f-9646-6da464b6e004</UUID>
+                    <description><![CDATA[Generated description for concept referred to by key "StringType:0.0.1"]]></description>
+                </value>
+            </entry>
+            <entry>
+                <key>
+                    <name>context</name>
+                    <version>0.0.1</version>
+                </key>
+                <value>
+                    <key>
+                        <name>context</name>
+                        <version>0.0.1</version>
+                    </key>
+                    <UUID>0ce9168c-e6df-414f-9646-6da464b6e005</UUID>
+                    <description><![CDATA[Generated description for concept referred to by key "context:0.0.1"]]></description>
+                </value>
+            </entry>
+            <entry>
+                <key>
+                    <name>contextAlbum0</name>
+                    <version>0.0.1</version>
+                </key>
+                <value>
+                    <key>
+                        <name>contextAlbum0</name>
+                        <version>0.0.1</version>
+                    </key>
+                    <UUID>0ce9168c-e6df-414f-9646-6da464b6e006</UUID>
+                    <description><![CDATA[Generated description for concept referred to by key "contextAlbum0:0.0.1"]]></description>
+                </value>
+            </entry>
+            <entry>
+                <key>
+                    <name>contextAlbum1</name>
+                    <version>0.0.1</version>
+                </key>
+                <value>
+                    <key>
+                        <name>contextAlbum1</name>
+                        <version>0.0.1</version>
+                    </key>
+                    <UUID>0ce9168c-e6df-414f-9646-6da464b6e007</UUID>
+                    <description><![CDATA[Generated description for concept referred to by key "contextAlbum1:0.0.1"]]></description>
+                </value>
+            </entry>
+            <entry>
+                <key>
+                    <name>eventContextItem0</name>
+                    <version>0.0.1</version>
+                </key>
+                <value>
+                    <key>
+                        <name>eventContextItem0</name>
+                        <version>0.0.1</version>
+                    </key>
+                    <UUID>0ce9168c-e6df-414f-9646-6da464b6e008</UUID>
+                    <description><![CDATA[Generated description for concept referred to by key "eventContextItem0:0.0.1"]]></description>
+                </value>
+            </entry>
+            <entry>
+                <key>
+                    <name>eventContextItem1</name>
+                    <version>0.0.1</version>
+                </key>
+                <value>
+                    <key>
+                        <name>eventContextItem1</name>
+                        <version>0.0.1</version>
+                    </key>
+                    <UUID>0ce9168c-e6df-414f-9646-6da464b6e009</UUID>
+                    <description><![CDATA[Generated description for concept referred to by key "eventContextItem1:0.0.1"]]></description>
+                </value>
+            </entry>
+            <entry>
+                <key>
+                    <name>events</name>
+                    <version>0.0.1</version>
+                </key>
+                <value>
+                    <key>
+                        <name>events</name>
+                        <version>0.0.1</version>
+                    </key>
+                    <UUID>0ce9168c-e6df-414f-9646-6da464b6e010</UUID>
+                    <description><![CDATA[Generated description for concept referred to by key "events:0.0.1"]]></description>
+                </value>
+            </entry>
+            <entry>
+                <key>
+                    <name>inEvent</name>
+                    <version>0.0.1</version>
+                </key>
+                <value>
+                    <key>
+                        <name>inEvent</name>
+                        <version>0.0.1</version>
+                    </key>
+                    <UUID>0ce9168c-e6df-414f-9646-6da464b6e011</UUID>
+                    <description><![CDATA[Generated description for concept referred to by key "inEvent:0.0.1"]]></description>
+                </value>
+            </entry>
+            <entry>
+                <key>
+                    <name>outEvent0</name>
+                    <version>0.0.1</version>
+                </key>
+                <value>
+                    <key>
+                        <name>outEvent0</name>
+                        <version>0.0.1</version>
+                    </key>
+                    <UUID>0ce9168c-e6df-414f-9646-6da464b6e012</UUID>
+                    <description><![CDATA[Generated description for concept referred to by key "outEvent0:0.0.1"]]></description>
+                </value>
+            </entry>
+            <entry>
+                <key>
+                    <name>outEvent1</name>
+                    <version>0.0.1</version>
+                </key>
+                <value>
+                    <key>
+                        <name>outEvent1</name>
+                        <version>0.0.1</version>
+                    </key>
+                    <UUID>0ce9168c-e6df-414f-9646-6da464b6e013</UUID>
+                    <description><![CDATA[Generated description for concept referred to by key "outEvent1:0.0.1"]]></description>
+                </value>
+            </entry>
+            <entry>
+                <key>
+                    <name>policies</name>
+                    <version>0.0.1</version>
+                </key>
+                <value>
+                    <key>
+                        <name>policies</name>
+                        <version>0.0.1</version>
+                    </key>
+                    <UUID>0ce9168c-e6df-414f-9646-6da464b6e014</UUID>
+                    <description><![CDATA[Generated description for concept referred to by key "policies:0.0.1"]]></description>
+                </value>
+            </entry>
+            <entry>
+                <key>
+                    <name>policy</name>
+                    <version>0.0.1</version>
+                </key>
+                <value>
+                    <key>
+                        <name>policy</name>
+                        <version>0.0.1</version>
+                    </key>
+                    <UUID>0ce9168c-e6df-414f-9646-6da464b6e015</UUID>
+                    <description><![CDATA[Generated description for concept referred to by key "policy:0.0.1"]]></description>
+                </value>
+            </entry>
+            <entry>
+                <key>
+                    <name>task</name>
+                    <version>0.0.1</version>
+                </key>
+                <value>
+                    <key>
+                        <name>task</name>
+                        <version>0.0.1</version>
+                    </key>
+                    <UUID>0ce9168c-e6df-414f-9646-6da464b6e016</UUID>
+                    <description><![CDATA[Generated description for concept referred to by key "task:0.0.1"]]></description>
+                </value>
+            </entry>
+            <entry>
+                <key>
+                    <name>tasks</name>
+                    <version>0.0.1</version>
+                </key>
+                <value>
+                    <key>
+                        <name>tasks</name>
+                        <version>0.0.1</version>
+                    </key>
+                    <UUID>0ce9168c-e6df-414f-9646-6da464b6e017</UUID>
+                    <description><![CDATA[Generated description for concept referred to by key "tasks:0.0.1"]]></description>
+                </value>
+            </entry>
+        </keyInfoMap>
+    </keyInformation>
+    <policies>
+        <key>
+            <name>policies</name>
+            <version>0.0.1</version>
+        </key>
+        <policyMap>
+            <entry>
+                <key>
+                    <name>policy</name>
+                    <version>0.0.1</version>
+                </key>
+                <value>
+                    <policyKey>
+                        <name>policy</name>
+                        <version>0.0.1</version>
+                    </policyKey>
+                    <template>FREEFORM</template>
+                    <state>
+                        <entry>
+                            <key>state</key>
+                            <value>
+                                <stateKey>
+                                    <parentKeyName>policy</parentKeyName>
+                                    <parentKeyVersion>0.0.1</parentKeyVersion>
+                                    <parentLocalName>NULL</parentLocalName>
+                                    <localName>state</localName>
+                                </stateKey>
+                                <trigger>
+                                    <name>inEvent</name>
+                                    <version>0.0.1</version>
+                                </trigger>
+                                <stateOutputs>
+                                    <entry>
+                                        <key>stateOutput0</key>
+                                        <value>
+                                            <key>
+                                                <parentKeyName>policy</parentKeyName>
+                                                <parentKeyVersion>0.0.1</parentKeyVersion>
+                                                <parentLocalName>state</parentLocalName>
+                                                <localName>stateOutput0</localName>
+                                            </key>
+                                            <outgoingEvent>
+                                                <name>outEvent0</name>
+                                                <version>0.0.1</version>
+                                            </outgoingEvent>
+                                            <nextState>
+                                                <parentKeyName>NULL</parentKeyName>
+                                                <parentKeyVersion>0.0.0</parentKeyVersion>
+                                                <parentLocalName>NULL</parentLocalName>
+                                                <localName>NULL</localName>
+                                            </nextState>
+                                        </value>
+                                    </entry>
+                                </stateOutputs>
+                                <contextAlbumReference>
+                                    <name>contextAlbum0</name>
+                                    <version>0.0.1</version>
+                                </contextAlbumReference>
+                                <contextAlbumReference>
+                                    <name>contextAlbum1</name>
+                                    <version>0.0.1</version>
+                                </contextAlbumReference>
+                                <taskSelectionLogic>
+                                    <key>taskSelectionLogic</key>
+                                    <logicFlavour>MVEL</logicFlavour>
+                                    <logic><![CDATA[Some TS logic]]></logic>
+                                </taskSelectionLogic>
+                                <defaultTask>
+                                    <name>task</name>
+                                    <version>0.0.1</version>
+                                </defaultTask>
+                                <taskReferences>
+                                    <entry>
+                                        <key>
+                                            <name>task</name>
+                                            <version>0.0.1</version>
+                                        </key>
+                                        <value>
+                                            <key>
+                                                <parentKeyName>policy</parentKeyName>
+                                                <parentKeyVersion>0.0.1</parentKeyVersion>
+                                                <parentLocalName>state</parentLocalName>
+                                                <localName>task</localName>
+                                            </key>
+                                            <outputType>DIRECT</outputType>
+                                            <output>
+                                                <parentKeyName>policy</parentKeyName>
+                                                <parentKeyVersion>0.0.1</parentKeyVersion>
+                                                <parentLocalName>state</parentLocalName>
+                                                <localName>stateOutput0</localName>
+                                            </output>
+                                        </value>
+                                    </entry>
+                                </taskReferences>
+                            </value>
+                        </entry>
+                    </state>
+                    <firstState>state</firstState>
+                </value>
+            </entry>
+        </policyMap>
+    </policies>
+    <tasks>
+        <key>
+            <name>tasks</name>
+            <version>0.0.1</version>
+        </key>
+        <taskMap>
+            <entry>
+                <key>
+                    <name>task</name>
+                    <version>0.0.1</version>
+                </key>
+                <value>
+                    <key>
+                        <name>task</name>
+                        <version>0.0.1</version>
+                    </key>
+                    <inputFields>
+                        <entry>
+                            <key>IEPAR0</key>
+                            <value>
+                                <key>IEPAR0</key>
+                                <fieldSchemaKey>
+                                    <name>eventContextItem0</name>
+                                    <version>0.0.1</version>
+                                </fieldSchemaKey>
+                            </value>
+                        </entry>
+                        <entry>
+                            <key>IEPAR1</key>
+                            <value>
+                                <key>IEPAR1</key>
+                                <fieldSchemaKey>
+                                    <name>eventContextItem1</name>
+                                    <version>0.0.1</version>
+                                </fieldSchemaKey>
+                            </value>
+                        </entry>
+                    </inputFields>
+                    <outputFields>
+                        <entry>
+                            <key>OE0PAR0</key>
+                            <value>
+                                <key>OE0PAR0</key>
+                                <fieldSchemaKey>
+                                    <name>eventContextItem0</name>
+                                    <version>0.0.1</version>
+                                </fieldSchemaKey>
+                            </value>
+                        </entry>
+                        <entry>
+                            <key>OE0PAR1</key>
+                            <value>
+                                <key>OE0PAR1</key>
+                                <fieldSchemaKey>
+                                    <name>eventContextItem1</name>
+                                    <version>0.0.1</version>
+                                </fieldSchemaKey>
+                            </value>
+                        </entry>
+                        <entry>
+                            <key>OE1PAR0</key>
+                            <value>
+                                <key>OE1PAR0</key>
+                                <fieldSchemaKey>
+                                    <name>eventContextItem0</name>
+                                    <version>0.0.1</version>
+                                </fieldSchemaKey>
+                            </value>
+                        </entry>
+                        <entry>
+                            <key>OE1PAR1</key>
+                            <value>
+                                <key>OE1PAR1</key>
+                                <fieldSchemaKey>
+                                    <name>eventContextItem1</name>
+                                    <version>0.0.1</version>
+                                </fieldSchemaKey>
+                            </value>
+                        </entry>
+                    </outputFields>
+                    <taskParameters>
+                        <entry>
+                            <key>taskParameter0</key>
+                            <value>
+                                <key>
+                                    <parentKeyName>task</parentKeyName>
+                                    <parentKeyVersion>0.0.1</parentKeyVersion>
+                                    <parentLocalName>NULL</parentLocalName>
+                                    <localName>taskParameter0</localName>
+                                </key>
+                                <defaultValue>Task parameter 0 value</defaultValue>
+                            </value>
+                        </entry>
+                        <entry>
+                            <key>taskParameter1</key>
+                            <value>
+                                <key>
+                                    <parentKeyName>task</parentKeyName>
+                                    <parentKeyVersion>0.0.1</parentKeyVersion>
+                                    <parentLocalName>NULL</parentLocalName>
+                                    <localName>taskParameter1</localName>
+                                </key>
+                                <defaultValue>Task parameter 1 value</defaultValue>
+                            </value>
+                        </entry>
+                    </taskParameters>
+                    <contextAlbumReference>
+                        <name>contextAlbum0</name>
+                        <version>0.0.1</version>
+                    </contextAlbumReference>
+                    <contextAlbumReference>
+                        <name>contextAlbum1</name>
+                        <version>0.0.1</version>
+                    </contextAlbumReference>
+                    <taskLogic>
+                        <key>taskLogic</key>
+                        <logicFlavour>MVEL</logicFlavour>
+                        <logic><![CDATA[Some task logic]]></logic>
+                    </taskLogic>
+                </value>
+            </entry>
+        </taskMap>
+    </tasks>
+    <events>
+        <key>
+            <name>events</name>
+            <version>0.0.1</version>
+        </key>
+        <eventMap>
+            <entry>
+                <key>
+                    <name>inEvent</name>
+                    <version>0.0.1</version>
+                </key>
+                <value>
+                    <key>
+                        <name>inEvent</name>
+                        <version>0.0.1</version>
+                    </key>
+                    <nameSpace>org.onap.policy.apex.model.policymodel.events</nameSpace>
+                    <source>Source</source>
+                    <target>Target</target>
+                    <parameter>
+                        <entry>
+                            <key>IEPAR0</key>
+                            <value>
+                                <key>IEPAR0</key>
+                                <fieldSchemaKey>
+                                    <name>eventContextItem0</name>
+                                    <version>0.0.1</version>
+                                </fieldSchemaKey>
+                            </value>
+                        </entry>
+                        <entry>
+                            <key>IEPAR1</key>
+                            <value>
+                                <key>IEPAR1</key>
+                                <fieldSchemaKey>
+                                    <name>eventContextItem1</name>
+                                    <version>0.0.1</version>
+                                </fieldSchemaKey>
+                            </value>
+                        </entry>
+                    </parameter>
+                </value>
+            </entry>
+            <entry>
+                <key>
+                    <name>outEvent0</name>
+                    <version>0.0.1</version>
+                </key>
+                <value>
+                    <key>
+                        <name>outEvent0</name>
+                        <version>0.0.1</version>
+                    </key>
+                    <nameSpace>org.onap.policy.apex.model.policymodel.events</nameSpace>
+                    <source>Source</source>
+                    <target>Target</target>
+                    <parameter>
+                        <entry>
+                            <key>OE0PAR0</key>
+                            <value>
+                                <key>OE0PAR0</key>
+                                <fieldSchemaKey>
+                                    <name>eventContextItem0</name>
+                                    <version>0.0.1</version>
+                                </fieldSchemaKey>
+                            </value>
+                        </entry>
+                        <entry>
+                            <key>OE0PAR1</key>
+                            <value>
+                                <key>OE0PAR1</key>
+                                <fieldSchemaKey>
+                                    <name>eventContextItem1</name>
+                                    <version>0.0.1</version>
+                                </fieldSchemaKey>
+                            </value>
+                        </entry>
+                        <entry>
+                            <key>OE1PAR0</key>
+                            <value>
+                                <key>OE1PAR0</key>
+                                <fieldSchemaKey>
+                                    <name>eventContextItem0</name>
+                                    <version>0.0.1</version>
+                                </fieldSchemaKey>
+                            </value>
+                        </entry>
+                        <entry>
+                            <key>OE1PAR1</key>
+                            <value>
+                                <key>OE1PAR1</key>
+                                <fieldSchemaKey>
+                                    <name>eventContextItem1</name>
+                                    <version>0.0.1</version>
+                                </fieldSchemaKey>
+                            </value>
+                        </entry>
+                    </parameter>
+                </value>
+            </entry>
+            <entry>
+                <key>
+                    <name>outEvent1</name>
+                    <version>0.0.1</version>
+                </key>
+                <value>
+                    <key>
+                        <name>outEvent1</name>
+                        <version>0.0.1</version>
+                    </key>
+                    <nameSpace>org.onap.policy.apex.model.policymodel.events</nameSpace>
+                    <source>Source</source>
+                    <target>Target</target>
+                    <parameter>
+                        <entry>
+                            <key>OE1PAR0</key>
+                            <value>
+                                <key>OE1PAR0</key>
+                                <fieldSchemaKey>
+                                    <name>eventContextItem0</name>
+                                    <version>0.0.1</version>
+                                </fieldSchemaKey>
+                            </value>
+                        </entry>
+                        <entry>
+                            <key>OE1PAR1</key>
+                            <value>
+                                <key>OE1PAR1</key>
+                                <fieldSchemaKey>
+                                    <name>eventContextItem1</name>
+                                    <version>0.0.1</version>
+                                </fieldSchemaKey>
+                            </value>
+                        </entry>
+                    </parameter>
+                </value>
+            </entry>
+        </eventMap>
+    </events>
+    <albums>
+        <key xmlns="">
+            <name xmlns="http://www.onap.org/policy/apex-pdp">context</name>
+            <version xmlns="http://www.onap.org/policy/apex-pdp">0.0.1</version>
+        </key>
+        <albums xmlns="">
+            <entry>
+                <key>
+                    <name xmlns="http://www.onap.org/policy/apex-pdp">contextAlbum0</name>
+                    <version xmlns="http://www.onap.org/policy/apex-pdp">0.0.1</version>
+                </key>
+                <value>
+                    <key>
+                        <name xmlns="http://www.onap.org/policy/apex-pdp">contextAlbum0</name>
+                        <version xmlns="http://www.onap.org/policy/apex-pdp">0.0.1</version>
+                    </key>
+                    <scope>APPLICATION</scope>
+                    <isWritable>true</isWritable>
+                    <itemSchema>
+                        <name xmlns="http://www.onap.org/policy/apex-pdp">MapType</name>
+                        <version xmlns="http://www.onap.org/policy/apex-pdp">0.0.1</version>
+                    </itemSchema>
+                </value>
+            </entry>
+            <entry>
+                <key>
+                    <name xmlns="http://www.onap.org/policy/apex-pdp">contextAlbum1</name>
+                    <version xmlns="http://www.onap.org/policy/apex-pdp">0.0.1</version>
+                </key>
+                <value>
+                    <key>
+                        <name xmlns="http://www.onap.org/policy/apex-pdp">contextAlbum1</name>
+                        <version xmlns="http://www.onap.org/policy/apex-pdp">0.0.1</version>
+                    </key>
+                    <scope>GLOBAL</scope>
+                    <isWritable>false</isWritable>
+                    <itemSchema>
+                        <name xmlns="http://www.onap.org/policy/apex-pdp">StringType</name>
+                        <version xmlns="http://www.onap.org/policy/apex-pdp">0.0.1</version>
+                    </itemSchema>
+                </value>
+            </entry>
+        </albums>
+    </albums>
+    <schemas>
+        <key xmlns="">
+            <name xmlns="http://www.onap.org/policy/apex-pdp">ContextSchemas</name>
+            <version xmlns="http://www.onap.org/policy/apex-pdp">0.0.1</version>
+        </key>
+        <schemas xmlns="">
+            <entry>
+                <key>
+                    <name xmlns="http://www.onap.org/policy/apex-pdp">MapType</name>
+                    <version xmlns="http://www.onap.org/policy/apex-pdp">0.0.1</version>
+                </key>
+                <value>
+                    <key>
+                        <name xmlns="http://www.onap.org/policy/apex-pdp">MapType</name>
+                        <version xmlns="http://www.onap.org/policy/apex-pdp">0.0.1</version>
+                    </key>
+                    <schemaFlavour>Java</schemaFlavour>
+                    <schemaDefinition>org.onap.policy.apex.model.policymodel.concepts.TestContextItem00A</schemaDefinition>
+                </value>
+            </entry>
+            <entry>
+                <key>
+                    <name xmlns="http://www.onap.org/policy/apex-pdp">StringType</name>
+                    <version xmlns="http://www.onap.org/policy/apex-pdp">0.0.1</version>
+                </key>
+                <value>
+                    <key>
+                        <name xmlns="http://www.onap.org/policy/apex-pdp">StringType</name>
+                        <version xmlns="http://www.onap.org/policy/apex-pdp">0.0.1</version>
+                    </key>
+                    <schemaFlavour>Java</schemaFlavour>
+                    <schemaDefinition>org.onap.policy.apex.model.policymodel.concepts.TestContextItem000</schemaDefinition>
+                </value>
+            </entry>
+            <entry>
+                <key>
+                    <name xmlns="http://www.onap.org/policy/apex-pdp">eventContextItem0</name>
+                    <version xmlns="http://www.onap.org/policy/apex-pdp">0.0.1</version>
+                </key>
+                <value>
+                    <key>
+                        <name xmlns="http://www.onap.org/policy/apex-pdp">eventContextItem0</name>
+                        <version xmlns="http://www.onap.org/policy/apex-pdp">0.0.1</version>
+                    </key>
+                    <schemaFlavour>Java</schemaFlavour>
+                    <schemaDefinition>java.lang.String</schemaDefinition>
+                </value>
+            </entry>
+            <entry>
+                <key>
+                    <name xmlns="http://www.onap.org/policy/apex-pdp">eventContextItem1</name>
+                    <version xmlns="http://www.onap.org/policy/apex-pdp">0.0.1</version>
+                </key>
+                <value>
+                    <key>
+                        <name xmlns="http://www.onap.org/policy/apex-pdp">eventContextItem1</name>
+                        <version xmlns="http://www.onap.org/policy/apex-pdp">0.0.1</version>
+                    </key>
+                    <schemaFlavour>Java</schemaFlavour>
+                    <schemaDefinition>java.lang.Long</schemaDefinition>
+                </value>
+            </entry>
+        </schemas>
+    </schemas>
+</apexPolicyModel>