Add DAO module for Models

This patch set fixes some typos and license headers.

Issue-ID: POLICY-1195
Change-Id: I2d15b00fcb50ea92746ab7c5a87b57efa07196fe
Signed-off-by: liamfallon <liam.fallon@est.tech>
diff --git a/.gitignore b/.gitignore
index 7d31072..21a4ea9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,6 +8,7 @@
 target
 .metadata/
 /bin/
+bin/
 .idea
 *.iml
 *.ipr
diff --git a/models-base/pom.xml b/models-base/pom.xml
index d2f8d87..712bc91 100644
--- a/models-base/pom.xml
+++ b/models-base/pom.xml
@@ -30,16 +30,4 @@
     <artifactId>policy-models-base</artifactId>
     <name>${project.artifactId}</name>
     <description>[${project.parent.artifactId}] module provides basic model handling for the ONAP Policy Framework</description>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.onap.policy.common</groupId>
-            <artifactId>utils</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-api</artifactId>
-        </dependency>
-    </dependencies>
 </project>
diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfConcept.java b/models-base/src/main/java/org/onap/policy/models/base/PfConcept.java
index 99eee8d..b74b037 100644
--- a/models-base/src/main/java/org/onap/policy/models/base/PfConcept.java
+++ b/models-base/src/main/java/org/onap/policy/models/base/PfConcept.java
@@ -23,17 +23,13 @@
 import java.io.Serializable;
 import java.util.List;
 
-import javax.xml.bind.annotation.XmlType;
-
 import org.onap.policy.common.utils.validation.Assertions;
 
 /**
- * This class is the base class for all model concept classes. It enforces implementation of
- * abstract methods and interfaces on all concepts that are sub-classes of this class.
+ * This class is the base class for all Policy Framework concept classes. It enforces implementation
+ * of abstract methods and interfaces on all concepts that are sub-classes of this class.
  */
 
-@XmlType(name = "PfConcept", namespace = "http://www.onap.org/policy/models")
-
 public abstract class PfConcept implements Serializable, Comparable<PfConcept> {
     private static final long serialVersionUID = -7434939557282697490L;
 
@@ -63,7 +59,7 @@
      * Gets a list of all keys for this concept and all concepts that are defined or referenced by
      * this concept and its sub-concepts.
      *
-     * @return the keys used by this concept and it's contained concepts
+     * @return the keys used by this concept and its contained concepts
      */
     public abstract List<PfKey> getKeys();
 
diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfConceptGetter.java b/models-base/src/main/java/org/onap/policy/models/base/PfConceptGetter.java
new file mode 100644
index 0000000..b1b8984
--- /dev/null
+++ b/models-base/src/main/java/org/onap/policy/models/base/PfConceptGetter.java
@@ -0,0 +1,76 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.models.base;
+
+import java.util.Set;
+
+/**
+ * This interface is used to allow get methods to be placed on concepts that have embedded maps.
+ *
+ * <p>It forces those concepts with maps to implement the get methods specified on this interface as convenience methods
+ * to avoid concept users having to use a second level of referencing to access concepts in the maps.
+ *
+ * @param <C> the type of concept on which the interface is applied.
+ */
+public interface PfConceptGetter<C> {
+
+    /**
+     * Get the latest version for a concept with the given key.
+     *
+     * @param conceptKey The key of the concept
+     * @return The concept
+     */
+    C get(PfConceptKey conceptKey);
+
+    /**
+     * Get the latest version for a concept with the given key name.
+     *
+     * @param conceptKeyName The name of the concept
+     * @return The concept
+     */
+    C get(String conceptKeyName);
+
+    /**
+     * Get the latest version for a concept with the given key name and version.
+     *
+     * @param conceptKeyName The name of the concept
+     * @param conceptKeyVersion The version of the concept
+     * @return The concept
+     */
+    C get(String conceptKeyName, String conceptKeyVersion);
+
+    /**
+     * Get the all versions for a concept with the given key name.
+     *
+     * @param conceptKeyName The name of the concept
+     * @return The concepts
+     */
+    Set<C> getAll(String conceptKeyName);
+
+    /**
+     * Get the all versions for a concept with the given key name and starting version.
+     *
+     * @param conceptKeyName The name of the concept
+     * @param conceptKeyVersion The first version version of the concept to get
+     * @return The concepts
+     */
+    Set<C> getAll(String conceptKeyName, String conceptKeyVersion);
+}
diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfConceptGetterImpl.java b/models-base/src/main/java/org/onap/policy/models/base/PfConceptGetterImpl.java
new file mode 100644
index 0000000..f07713a
--- /dev/null
+++ b/models-base/src/main/java/org/onap/policy/models/base/PfConceptGetterImpl.java
@@ -0,0 +1,129 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.models.base;
+
+import java.util.NavigableMap;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * Implements concept getting from navigable maps.
+ *
+ * @param <C> the type of concept on which the interface implementation is applied.
+ */
+public class PfConceptGetterImpl<C> implements PfConceptGetter<C> {
+
+    // The map from which to get concepts
+    private final NavigableMap<PfConceptKey, C> conceptMap;
+
+    /**
+     * Constructor that sets the concept map on which the getter methods in the interface will operate..
+     *
+     * @param conceptMap the concept map on which the method will operate
+     */
+    public PfConceptGetterImpl(final NavigableMap<PfConceptKey, C> conceptMap) {
+        this.conceptMap = conceptMap;
+    }
+
+    @Override
+    public C get(final PfConceptKey conceptKey) {
+        return conceptMap.get(conceptKey);
+    }
+
+    @Override
+    public C get(final String conceptKeyName) {
+        Assertions.argumentNotNull(conceptKeyName, "conceptKeyName may not be null");
+
+        // The very fist key that could have this name
+        final PfConceptKey lowestArtifactKey = new PfConceptKey(conceptKeyName, "0.0.1");
+
+        // Check if we found a key for our name
+        PfConceptKey foundKey = conceptMap.ceilingKey(lowestArtifactKey);
+        if (foundKey == null || !foundKey.getName().equals(conceptKeyName)) {
+            return null;
+        }
+
+        // Look for higher versions of the key
+        do {
+            final PfConceptKey nextkey = conceptMap.higherKey(foundKey);
+            if (nextkey == null || !nextkey.getName().equals(conceptKeyName)) {
+                break;
+            }
+            foundKey = nextkey;
+        }
+        while (true);
+
+        return conceptMap.get(foundKey);
+    }
+
+    @Override
+    public C get(final String conceptKeyName, final String conceptKeyVersion) {
+        Assertions.argumentNotNull(conceptKeyName, "conceptKeyName may not be null");
+
+        if (conceptKeyVersion != null) {
+            return conceptMap.get(new PfConceptKey(conceptKeyName, conceptKeyVersion));
+        } else {
+            return this.get(conceptKeyName);
+        }
+    }
+
+    @Override
+    public Set<C> getAll(final String conceptKeyName) {
+        return getAll(conceptKeyName, null);
+    }
+
+    @Override
+    public Set<C> getAll(final String conceptKeyName, final String conceptKeyVersion) {
+        final Set<C> returnSet = new TreeSet<>();
+
+        if (conceptKeyName == null) {
+            returnSet.addAll(conceptMap.values());
+            return returnSet;
+        }
+
+        // The very fist key that could have this name
+        final PfConceptKey lowestArtifactKey = new PfConceptKey(conceptKeyName, "0.0.1");
+        if (conceptKeyVersion != null) {
+            lowestArtifactKey.setVersion(conceptKeyVersion);
+        }
+
+        // Check if we found a key for our name
+        PfConceptKey foundKey = conceptMap.ceilingKey(lowestArtifactKey);
+        if (foundKey == null || !foundKey.getName().equals(conceptKeyName)) {
+            return returnSet;
+        }
+        returnSet.add(conceptMap.get(foundKey));
+
+        // Look for higher versions of the key
+        do {
+            foundKey = conceptMap.higherKey(foundKey);
+            if (foundKey == null || !foundKey.getName().equals(conceptKeyName)) {
+                break;
+            }
+            returnSet.add(conceptMap.get(foundKey));
+        }
+        while (true);
+
+        return returnSet;
+    }
+}
diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfConceptKey.java b/models-base/src/main/java/org/onap/policy/models/base/PfConceptKey.java
index 6ebb888..efcbe39 100644
--- a/models-base/src/main/java/org/onap/policy/models/base/PfConceptKey.java
+++ b/models-base/src/main/java/org/onap/policy/models/base/PfConceptKey.java
@@ -25,29 +25,24 @@
 
 import javax.persistence.Column;
 import javax.persistence.Embeddable;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
 
 import org.onap.policy.common.utils.validation.Assertions;
 import org.onap.policy.models.base.PfValidationResult.ValidationResult;
 
 /**
- * An artifact key uniquely identifies every first order entity in the system. Every first order
- * concept in the system must have an {@link PfConceptKey} to identify it. Concepts that are wholly
- * contained in another concept are identified using a {@link AxReferenceKey} key.
+ * An concept key uniquely identifies every first order entity in the system. Every first order concept in the system
+ * must have an {@link PfConceptKey} to identify it. Concepts that are wholly contained in another concept are
+ * identified using a {@link PfReferenceKey} key.
  *
  * <p>Key validation checks that the name and version fields match the NAME_REGEXP and VERSION_REGEXP
  * regular expressions respectively.
  */
 @Embeddable
-@XmlAccessorType(XmlAccessType.FIELD)
-@XmlRootElement(name = "pfConceptKey", namespace = "http://www.onap.org/policy/models")
-
-@XmlType(name = "PfConceptKey", namespace = "http://www.onap.org/policy/models", propOrder = {"name", "version"})
-
+@Data
+@EqualsAndHashCode(callSuper = false)
 public class PfConceptKey extends PfKey {
     private static final long serialVersionUID = 8932717618579392561L;
 
@@ -55,15 +50,13 @@
     private static final String VERSION_TOKEN = "version";
 
     @Column(name = NAME_TOKEN)
-    @XmlElement(required = true)
     private String name;
 
     @Column(name = VERSION_TOKEN)
-    @XmlElement(required = true)
     private String version;
 
     /**
-     * The default constructor creates a null artifact key.
+     * The default constructor creates a null concept key.
      */
     public PfConceptKey() {
         this(NULL_KEY_NAME, NULL_KEY_VERSION);
@@ -112,9 +105,9 @@
     }
 
     /**
-     * Get a null artifact key.
+     * Get a null concept key.
      *
-     * @return a null artifact key
+     * @return a null concept key
      */
     public static final PfConceptKey getNullKey() {
         return new PfConceptKey(PfKey.NULL_KEY_NAME, PfKey.NULL_KEY_VERSION);
@@ -137,58 +130,22 @@
         return name + ':' + version;
     }
 
-    /**
-     * Gets the key name.
-     *
-     * @return the key name
-     */
-    public String getName() {
-        return name;
-    }
-
-    /**
-     * Sets the key name.
-     *
-     * @param name the key name
-     */
-    public void setName(final String name) {
-        this.name = Assertions.validateStringParameter(NAME_TOKEN, name, NAME_REGEXP);
-    }
-
-    /**
-     * Gets the key version.
-     *
-     * @return the key version
-     */
-    public String getVersion() {
-        return version;
-    }
-
-    /**
-     * Sets the key version.
-     *
-     * @param version the key version
-     */
-    public void setVersion(final String version) {
-        this.version = Assertions.validateStringParameter(VERSION_TOKEN, version, VERSION_REGEXP);
-    }
-
     @Override
     public PfKey.Compatibility getCompatibility(final PfKey otherKey) {
         if (!(otherKey instanceof PfConceptKey)) {
             return Compatibility.DIFFERENT;
         }
-        final PfConceptKey otherArtifactKey = (PfConceptKey) otherKey;
+        final PfConceptKey otherConceptKey = (PfConceptKey) otherKey;
 
-        if (this.equals(otherArtifactKey)) {
+        if (this.equals(otherConceptKey)) {
             return Compatibility.IDENTICAL;
         }
-        if (!this.getName().equals(otherArtifactKey.getName())) {
+        if (!this.getName().equals(otherConceptKey.getName())) {
             return Compatibility.DIFFERENT;
         }
 
         final String[] thisVersionArray = getVersion().split("\\.");
-        final String[] otherVersionArray = otherArtifactKey.getVersion().split("\\.");
+        final String[] otherVersionArray = otherConceptKey.getVersion().split("\\.");
 
         // There must always be at least one element in each version
         if (!thisVersionArray[0].equals(otherVersionArray[0])) {
@@ -196,7 +153,7 @@
         }
 
         if (thisVersionArray.length >= 2 && otherVersionArray.length >= 2
-                && !thisVersionArray[1].equals(otherVersionArray[1])) {
+                        && !thisVersionArray[1].equals(otherVersionArray[1])) {
             return Compatibility.MINOR;
         }
 
@@ -208,27 +165,27 @@
         if (!(otherKey instanceof PfConceptKey)) {
             return false;
         }
-        final PfConceptKey otherArtifactKey = (PfConceptKey) otherKey;
+        final PfConceptKey otherConceptKey = (PfConceptKey) otherKey;
 
-        final Compatibility compatibility = this.getCompatibility(otherArtifactKey);
+        final Compatibility compatibility = this.getCompatibility(otherConceptKey);
 
         return !(compatibility == Compatibility.DIFFERENT || compatibility == Compatibility.MAJOR);
     }
 
     @Override
     public PfValidationResult validate(final PfValidationResult result) {
-        final String nameValidationErrorMessage =
-                Assertions.getStringParameterValidationMessage(NAME_TOKEN, name, NAME_REGEXP);
+        final String nameValidationErrorMessage = Assertions.getStringParameterValidationMessage(NAME_TOKEN, name,
+                        NAME_REGEXP);
         if (nameValidationErrorMessage != null) {
             result.addValidationMessage(new PfValidationMessage(this, this.getClass(), ValidationResult.INVALID,
-                    "name invalid-" + nameValidationErrorMessage));
+                            "name invalid-" + nameValidationErrorMessage));
         }
 
-        final String versionValidationErrorMessage =
-                Assertions.getStringParameterValidationMessage(VERSION_TOKEN, version, VERSION_REGEXP);
+        final String versionValidationErrorMessage = Assertions.getStringParameterValidationMessage(VERSION_TOKEN,
+                        version, VERSION_REGEXP);
         if (versionValidationErrorMessage != null) {
             result.addValidationMessage(new PfValidationMessage(this, this.getClass(), ValidationResult.INVALID,
-                    "version invalid-" + versionValidationErrorMessage));
+                            "version invalid-" + versionValidationErrorMessage));
         }
 
         return result;
@@ -241,19 +198,6 @@
     }
 
     @Override
-    public String toString() {
-        final StringBuilder builder = new StringBuilder();
-        builder.append(this.getClass().getSimpleName());
-        builder.append(":(");
-        builder.append("name=");
-        builder.append(name);
-        builder.append(",version=");
-        builder.append(version);
-        builder.append(")");
-        return builder.toString();
-    }
-
-    @Override
     public PfConcept copyTo(final PfConcept target) {
         Assertions.argumentNotNull(target, "target may not be null");
 
@@ -268,35 +212,6 @@
     }
 
     @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + name.hashCode();
-        result = prime * result + version.hashCode();
-        return result;
-    }
-
-    @Override
-    public boolean equals(final Object obj) {
-        if (obj == null) {
-            return false;
-        }
-        if (this == obj) {
-            return true;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-
-        final PfConceptKey other = (PfConceptKey) obj;
-
-        if (!name.equals(other.name)) {
-            return false;
-        }
-        return version.equals(other.version);
-    }
-
-    @Override
     public int compareTo(final PfConcept otherObj) {
         Assertions.argumentNotNull(otherObj, "comparison object may not be null");
 
diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfKey.java b/models-base/src/main/java/org/onap/policy/models/base/PfKey.java
index 16e70a2..dda4cdc 100644
--- a/models-base/src/main/java/org/onap/policy/models/base/PfKey.java
+++ b/models-base/src/main/java/org/onap/policy/models/base/PfKey.java
@@ -21,8 +21,8 @@
 package org.onap.policy.models.base;
 
 /**
- * The key uniquely identifies every entity in the system. This class is an abstract class to give a
- * common parent for all key types in the system.
+ * The key uniquely identifies every entity in the system. This class is an abstract class to give a common parent for
+ * all key types in the system.
  */
 public abstract class PfKey extends PfConcept {
     private static final long serialVersionUID = 6281159885962014041L;
@@ -49,18 +49,15 @@
         /** The keys have different names. */
         DIFFERENT,
         /**
-         * The name of the key matches but the Major version number of the keys is different (x in
-         * x.y.z do not match).
+         * The name of the key matches but the Major version number of the keys is different (x in x.y.z do not match).
          */
         MAJOR,
         /**
-         * The name of the key matches but the Minor version number of the keys is different (y in
-         * x.y.z do not match).
+         * The name of the key matches but the Minor version number of the keys is different (y in x.y.z do not match).
          */
         MINOR,
         /**
-         * The name of the key matches but the Patch version number of the keys is different (z in
-         * x.y.z do not match).
+         * The name of the key matches but the Patch version number of the keys is different (z in x.y.z do not match).
          */
         PATCH,
         /** The keys match completely. */
@@ -95,8 +92,7 @@
     public abstract Compatibility getCompatibility(PfKey otherKey);
 
     /**
-     * Check if two keys are compatible, that is the keys are IDENTICAL or have only MINOR, PATCH
-     * differences.
+     * Check if two keys are compatible, that is the keys are IDENTICAL or have only MINOR, PATCH differences.
      *
      * @param otherKey the key to check compatibility against
      * @return true, if the keys are compatible
diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfKeyUse.java b/models-base/src/main/java/org/onap/policy/models/base/PfKeyUse.java
new file mode 100644
index 0000000..0eb55a7
--- /dev/null
+++ b/models-base/src/main/java/org/onap/policy/models/base/PfKeyUse.java
@@ -0,0 +1,153 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.models.base;
+
+import java.util.List;
+
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+import org.onap.policy.common.utils.validation.Assertions;
+import org.onap.policy.models.base.PfValidationResult.ValidationResult;
+
+/**
+ * This class records a usage of a key in the system. When the list of keys being used by a concept is built using the
+ * getKeys() method of the {@link PfConcept} class, an instance of this class is created for every key occurrence. The
+ * list of keys returned by the getKeys() method is a list of {@link PfKeyUse} objects.
+ *
+ * <p>Validation checks that each key is valid.
+ */
+@EqualsAndHashCode(callSuper = false)
+@ToString
+public class PfKeyUse extends PfKey {
+    private static final long serialVersionUID = 2007147220109881705L;
+
+    private PfKey usedKey;
+
+    /**
+     * The Default Constructor creates this concept with a null key.
+     */
+    public PfKeyUse() {
+        this(new PfConceptKey());
+    }
+
+    /**
+     * Copy constructor.
+     *
+     * @param copyConcept the concept to copy from
+     */
+    public PfKeyUse(final PfKeyUse copyConcept) {
+        super(copyConcept);
+    }
+
+    /**
+     * This constructor creates an instance of this class, and holds a reference to a used key.
+     *
+     * @param usedKey a used key
+     */
+    public PfKeyUse(final PfKey usedKey) {
+        Assertions.argumentNotNull(usedKey, "usedKey may not be null");
+        this.usedKey = usedKey;
+    }
+
+    @Override
+    public PfKey getKey() {
+        return usedKey;
+    }
+
+    @Override
+    public List<PfKey> getKeys() {
+        return usedKey.getKeys();
+    }
+
+    @Override
+    public String getId() {
+        return usedKey.getId();
+    }
+
+    /**
+     * Sets the key.
+     *
+     * @param key the key
+     */
+    public void setKey(final PfKey key) {
+        Assertions.argumentNotNull(key, "usedKey may not be null");
+        this.usedKey = key;
+    }
+
+    @Override
+    public PfKey.Compatibility getCompatibility(final PfKey otherKey) {
+        return usedKey.getCompatibility(otherKey);
+    }
+
+    @Override
+    public boolean isCompatible(final PfKey otherKey) {
+        return usedKey.isCompatible(otherKey);
+    }
+
+    @Override
+    public PfValidationResult validate(final PfValidationResult result) {
+        if (usedKey.equals(PfConceptKey.getNullKey())) {
+            result.addValidationMessage(new PfValidationMessage(usedKey, this.getClass(), ValidationResult.INVALID,
+                    "usedKey is a null key"));
+        }
+        return usedKey.validate(result);
+    }
+
+    @Override
+    public void clean() {
+        usedKey.clean();
+    }
+
+    @Override
+    public PfConcept copyTo(final PfConcept target) {
+        Assertions.argumentNotNull(target, "target may not be null");
+
+        final Object copyObject = target;
+        Assertions.instanceOf(copyObject, PfKeyUse.class);
+
+        final PfKeyUse copy = ((PfKeyUse) copyObject);
+        try {
+            copy.usedKey = usedKey.getClass().newInstance();
+        } catch (final Exception e) {
+            throw new PfModelRuntimeException("error copying concept key: " + e.getMessage(), e);
+        }
+        usedKey.copyTo(copy.usedKey);
+
+        return copy;
+    }
+
+    @Override
+    public int compareTo(final PfConcept otherObj) {
+        Assertions.argumentNotNull(otherObj, "comparison object may not be null");
+
+        if (this == otherObj) {
+            return 0;
+        }
+        if (getClass() != otherObj.getClass()) {
+            return this.hashCode() - otherObj.hashCode();
+        }
+
+        final PfKeyUse other = (PfKeyUse) otherObj;
+
+        return usedKey.compareTo(other.usedKey);
+    }
+}
diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfModel.java b/models-base/src/main/java/org/onap/policy/models/base/PfModel.java
new file mode 100644
index 0000000..c9174bd
--- /dev/null
+++ b/models-base/src/main/java/org/onap/policy/models/base/PfModel.java
@@ -0,0 +1,303 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.models.base;
+
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.persistence.EmbeddedId;
+import javax.persistence.Entity;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.Table;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NonNull;
+
+import org.onap.policy.common.utils.validation.Assertions;
+import org.onap.policy.models.base.PfValidationResult.ValidationResult;
+
+/**
+ * This class is the base class for all models in the Policy Framework. All model classes inherit
+ * from this model so all models must have a key and have key information.
+ *
+ * <p>Validation checks that the model key is valid. It goes on to check for null keys and checks
+ * each key for uniqueness in the model. A check is carried out to ensure that an {@link PfKeyInfo}
+ * instance exists for every {@link PfConceptKey} key. For each {@link PfReferenceKey} instance, a
+ * check is made that its parent and local name are nut null and that a {@link PfKeyInfo} entry
+ * exists for its parent. Then a check is made that each used {@link PfConceptKey} and
+ * {@link PfReferenceKey} usage references a key that exists. Finally, a check is made to ensure
+ * that an {@link PfConceptKey} instance exists for every {@link PfKeyInfo} instance.
+ *
+ * @param <C> the type of concept on which the interface is applied.
+ */
+
+@Entity
+@Table(name = "PfModel")
+@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
+@Data
+@EqualsAndHashCode(callSuper = false)
+public abstract class PfModel extends PfConcept {
+    private static final String IS_A_NULL_KEY = " is a null key";
+
+    private static final long serialVersionUID = -771659065637205430L;
+
+    @EmbeddedId
+    @NonNull
+    private PfConceptKey key = PfConceptKey.getNullKey();
+
+    /**
+     * The Default Constructor creates this concept with a NULL artifact key.
+     */
+    public PfModel() {
+        this(new PfConceptKey());
+    }
+
+    /**
+     * Copy constructor.
+     *
+     * @param copyConcept the concept to copy from
+     */
+    public PfModel(final PfModel copyConcept) {
+        super(copyConcept);
+    }
+
+    /**
+     * Constructor to create this concept with the specified key.
+     *
+     * @param key the key of this concept
+     */
+    public PfModel(final PfConceptKey key) {
+        super();
+        Assertions.argumentNotNull(key, "key may not be null");
+
+        this.key = key;
+    }
+
+    /**
+     * Registers this model with the {@link PfModelService}. All models are registered with the
+     * model service so that models can be references from anywhere in the Policy Framework system
+     * without being passed as references through deep call chains.
+     */
+    public abstract void register();
+
+    @Override
+    public List<PfKey> getKeys() {
+        return key.getKeys();
+    }
+
+    @Override
+    public PfValidationResult validate(final PfValidationResult resultIn) {
+        PfValidationResult result = resultIn;
+
+        if (key.equals(PfConceptKey.getNullKey())) {
+            result.addValidationMessage(
+                    new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
+        }
+
+        result = key.validate(result);
+
+        // Key consistency check
+        final Set<PfConceptKey> artifactKeySet = new TreeSet<>();
+        final Set<PfReferenceKey> referenceKeySet = new TreeSet<>();
+        final Set<PfKeyUse> usedKeySet = new TreeSet<>();
+
+        for (final PfKey pfKey : this.getKeys()) {
+            // Check for the two type of keys we have
+            if (pfKey instanceof PfConceptKey) {
+                result = validateArtifactKeyInModel((PfConceptKey) pfKey, artifactKeySet, result);
+            } else if (pfKey instanceof PfReferenceKey) {
+                result = validateReferenceKeyInModel((PfReferenceKey) pfKey, referenceKeySet, result);
+            }
+            // It must be an PfKeyUse, nothing else is legal
+            else {
+                usedKeySet.add((PfKeyUse) pfKey);
+            }
+        }
+
+        // Check all reference keys have correct parent keys
+        for (final PfReferenceKey referenceKey : referenceKeySet) {
+            if (!artifactKeySet.contains(referenceKey.getParentConceptKey())) {
+                result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+                        "parent artifact key not found for reference key " + referenceKey));
+            }
+        }
+
+        result = validateKeyUses(usedKeySet, artifactKeySet, referenceKeySet, result);
+
+        return result;
+    }
+
+    /**
+     * Check for consistent usage of an artifact key in the model.
+     *
+     * @param artifactKey The artifact key to check
+     * @param artifactKeySet The set of artifact keys encountered so far, this key is appended to
+     *        the set
+     * @param result The validation result to append to
+     * @return the result of the validation
+     */
+    private PfValidationResult validateArtifactKeyInModel(final PfConceptKey artifactKey,
+            final Set<PfConceptKey> artifactKeySet, final PfValidationResult result) {
+        // Null key check
+        if (artifactKey.equals(PfConceptKey.getNullKey())) {
+            result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+                    "key " + artifactKey + IS_A_NULL_KEY));
+        }
+
+        // Null key name start check
+        if (artifactKey.getName().toUpperCase().startsWith(PfKey.NULL_KEY_NAME)) {
+            result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+                    "key " + artifactKey + " name starts with keyword " + PfKey.NULL_KEY_NAME));
+        }
+
+        // Unique key check
+        if (artifactKeySet.contains(artifactKey)) {
+            result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+                    "duplicate key " + artifactKey + " found"));
+        } else {
+            artifactKeySet.add(artifactKey);
+        }
+
+        return result;
+    }
+
+    /**
+     * Check for consistent usage of a reference key in the model.
+     *
+     * @param artifactKey The reference key to check
+     * @param referenceKeySet The set of reference keys encountered so far, this key is appended to
+     *        the set
+     * @param result The validation result to append to
+     * @return the result of the validation
+     */
+    private PfValidationResult validateReferenceKeyInModel(final PfReferenceKey referenceKey,
+            final Set<PfReferenceKey> referenceKeySet, final PfValidationResult result) {
+        // Null key check
+        if (referenceKey.equals(PfReferenceKey.getNullKey())) {
+            result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+                    "key " + referenceKey + IS_A_NULL_KEY));
+        }
+
+        // Null parent key check
+        if (referenceKey.getParentConceptKey().equals(PfConceptKey.getNullKey())) {
+            result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+                    "parent artifact key of key " + referenceKey + IS_A_NULL_KEY));
+        }
+
+        // Null local name check
+        if (referenceKey.getLocalName().equals(PfKey.NULL_KEY_NAME)) {
+            result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+                    "key " + referenceKey + " has a null local name"));
+        }
+
+        // Null key name start check
+        if (referenceKey.getParentConceptKey().getName().toUpperCase().startsWith(PfKey.NULL_KEY_NAME)) {
+            result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+                    "key " + referenceKey + " parent name starts with keyword " + PfKey.NULL_KEY_NAME));
+        }
+
+        // Unique key check
+        if (referenceKeySet.contains(referenceKey)) {
+            result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+                    "duplicate key " + referenceKey + " found"));
+        } else {
+            referenceKeySet.add(referenceKey);
+        }
+
+        return result;
+    }
+
+    /**
+     * Check for consistent usage of cross-key references in the model.
+     *
+     * @param usedKeySet The set of all keys used in the model
+     * @param artifactKeySet The set of artifact keys encountered so far, this key is appended to
+     *        the set
+     * @param referenceKeySet The set of reference keys encountered so far, this key is appended to
+     *        the set
+     * @param result The validation result to append to
+     * @return the result of the validation
+     */
+    private PfValidationResult validateKeyUses(final Set<PfKeyUse> usedKeySet, final Set<PfConceptKey> artifactKeySet,
+            final Set<PfReferenceKey> referenceKeySet, final PfValidationResult result) {
+        // Check all key uses
+        for (final PfKeyUse usedKey : usedKeySet) {
+            if (usedKey.getKey() instanceof PfConceptKey) {
+                // PfConceptKey usage, check the key exists
+                if (!artifactKeySet.contains(usedKey.getKey())) {
+                    result.addValidationMessage(new PfValidationMessage(usedKey.getKey(), this.getClass(),
+                            ValidationResult.INVALID, "an artifact key used in the model is not defined"));
+                }
+            } else {
+                // PfReferenceKey usage, check the key exists
+                if (!referenceKeySet.contains(usedKey.getKey())) {
+                    result.addValidationMessage(new PfValidationMessage(usedKey.getKey(), this.getClass(),
+                            ValidationResult.INVALID, "a reference key used in the model is not defined"));
+                }
+            }
+        }
+
+        return result;
+    }
+
+    @Override
+    public void clean() {
+        key.clean();
+    }
+
+    @Override
+    public PfConcept copyTo(final PfConcept target) {
+        Assertions.argumentNotNull(target, "target may not be null");
+
+        final Object copyObject = target;
+        Assertions.instanceOf(copyObject, PfModel.class);
+
+        final PfModel copy = ((PfModel) copyObject);
+        copy.setKey(new PfConceptKey(key));
+
+        return copy;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.lang.Comparable#compareTo(java.lang.Object)
+     */
+    @Override
+    public int compareTo(final PfConcept otherObj) {
+        if (otherObj == null) {
+            return -1;
+        }
+        if (this == otherObj) {
+            return 0;
+        }
+        if (getClass() != otherObj.getClass()) {
+            return this.hashCode() - otherObj.hashCode();
+        }
+
+        final PfModel other = (PfModel) otherObj;
+
+        return key.compareTo(other.key);
+    }
+}
diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfModelService.java b/models-base/src/main/java/org/onap/policy/models/base/PfModelService.java
new file mode 100644
index 0000000..c02de6a
--- /dev/null
+++ b/models-base/src/main/java/org/onap/policy/models/base/PfModelService.java
@@ -0,0 +1,104 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.models.base;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * The model service makes Policy Framework models available to all classes in a JVM.
+ *
+ * <p>The reason for having a model service is to avoid having to pass concept and model definitions
+ * down long call chains in modules such as the Policy Framework engine and editor. The model
+ * service makes the model and concept definitions available statically.
+ *
+ * <p>Note that the use of the model service means that only a single Policy Framework model of a
+ * particular type may exist in Policy Framework (particularly the engine) at any time. Of course
+ * the model in a JVM can be changed at any time provided all users of the model are stopped and
+ * restarted in an orderly manner.
+ */
+public abstract class PfModelService {
+    // The map holding the models
+    private static Map<Class<?>, PfConcept> modelMap = new ConcurrentHashMap<>();
+
+    /**
+     * This class is an abstract static class that cannot be extended.
+     */
+    private PfModelService() {}
+
+    /**
+     * Register a model with the model service.
+     *
+     * @param <M> the generic type
+     * @param modelClass the class of the model, used to index the model
+     * @param model The model
+     */
+    public static <M extends PfConcept> void registerModel(final Class<M> modelClass, final M model) {
+        modelMap.put(modelClass, model);
+    }
+
+    /**
+     * Remove a model from the model service.
+     *
+     * @param <M> the generic type
+     * @param modelClass the class of the model, used to index the model
+     */
+    public static <M extends PfConcept> void deregisterModel(final Class<M> modelClass) {
+        modelMap.remove(modelClass);
+    }
+
+    /**
+     * Get a model from the model service.
+     *
+     * @param <M> the generic type
+     * @param modelClass the class of the model, used to index the model
+     * @return The model
+     */
+    @SuppressWarnings("unchecked")
+    public static <M extends PfConcept> M getModel(final Class<M> modelClass) {
+        final M model = (M) modelMap.get(modelClass);
+
+        if (model == null) {
+            throw new PfModelRuntimeException(
+                    "Model for " + modelClass.getCanonicalName() + " not found in model service");
+        }
+
+        return model;
+    }
+
+    /**
+     * Check if a model is defined on the model service.
+     *
+     * @param <M> the generic type
+     * @param modelClass the class of the model, used to index the model
+     * @return true if the model is defined
+     */
+    public static <M extends PfConcept> boolean existsModel(final Class<M> modelClass) {
+        return modelMap.get(modelClass) != null;
+    }
+
+    /**
+     * Clear all models in the model service.
+     */
+    public static void clear() {
+        modelMap.clear();
+    }
+}
diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfReferenceKey.java b/models-base/src/main/java/org/onap/policy/models/base/PfReferenceKey.java
new file mode 100644
index 0000000..e3b92c0
--- /dev/null
+++ b/models-base/src/main/java/org/onap/policy/models/base/PfReferenceKey.java
@@ -0,0 +1,392 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.models.base;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.Column;
+import javax.persistence.Embeddable;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import org.onap.policy.common.utils.validation.Assertions;
+import org.onap.policy.models.base.PfValidationResult.ValidationResult;
+
+/**
+ * A reference key identifies entities in the system that are contained in other entities. Every contained concept in
+ * the system must have an {@link PfReferenceKey} to identify it. Non-contained first order concepts are identified
+ * using an {@link PfConceptKey} key.
+ *
+ * <p>An {@link PfReferenceKey} contains an {@link PfConceptKey} key reference to the first order entity that contains
+ * it. The local name of the reference key must uniquely identify the referenced concept among those concepts contained
+ * in the reference key's parent. In other words, if a parent concept has more than one child, the local name in the key
+ * of all its children must be unique.
+ *
+ * <p>If a reference key's parent is itself a reference key, then the parent's local name must be set in the reference
+ * key. If the parent is a first order concept, then the parent's local name in the key will be set to NULL.
+ *
+ * <p>Key validation checks that the parent name and parent version fields match the NAME_REGEXP and
+ * VERSION_REGEXP regular expressions respectively and that the local name fields match the
+ * LOCAL_NAME_REGEXP regular expression.
+ */
+@Embeddable
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class PfReferenceKey extends PfKey {
+    private static final String PARENT_KEY_NAME = "parentKeyName";
+    private static final String PARENT_KEY_VERSION = "parentKeyVersion";
+    private static final String PARENT_LOCAL_NAME = "parentLocalName";
+    private static final String LOCAL_NAME = "localName";
+
+    private static final long serialVersionUID = 8932717618579392561L;
+
+    /** Regular expression to specify the structure of local names in reference keys. */
+    public static final String LOCAL_NAME_REGEXP = "[A-Za-z0-9\\-_\\.]+|^$";
+
+    /** Regular expression to specify the structure of IDs in reference keys. */
+    public static final String REFERENCE_KEY_ID_REGEXP =
+                    "[A-Za-z0-9\\-_]+:[0-9].[0-9].[0-9]:[A-Za-z0-9\\-_]+:[A-Za-z0-9\\-_]+";
+
+    private static final int PARENT_NAME_FIELD = 0;
+    private static final int PARENT_VERSION_FIELD = 1;
+    private static final int PARENT_LOCAL_NAME_FIELD = 2;
+    private static final int LOCAL_NAME_FIELD = 3;
+
+    @Column(name = PARENT_KEY_NAME)
+    private String parentKeyName;
+
+    @Column(name = PARENT_KEY_VERSION)
+    private String parentKeyVersion;
+
+    @Column(name = PARENT_LOCAL_NAME)
+    private String parentLocalName;
+
+    @Column(name = LOCAL_NAME)
+    private String localName;
+
+    /**
+     * The default constructor creates a null reference key.
+     */
+    public PfReferenceKey() {
+        this(NULL_KEY_NAME, NULL_KEY_VERSION, NULL_KEY_NAME, NULL_KEY_NAME);
+    }
+
+    /**
+     * The Copy Constructor creates a key by copying another key.
+     *
+     * @param referenceKey
+     *        the reference key to copy from
+     */
+    public PfReferenceKey(final PfReferenceKey referenceKey) {
+        this(referenceKey.getParentKeyName(), referenceKey.getParentKeyVersion(), referenceKey.getParentLocalName(),
+                        referenceKey.getLocalName());
+    }
+
+    /**
+     * Constructor to create a null reference key for the specified parent concept key.
+     *
+     * @param pfConceptKey
+     *        the parent concept key of this reference key
+     */
+    public PfReferenceKey(final PfConceptKey pfConceptKey) {
+        this(pfConceptKey.getName(), pfConceptKey.getVersion(), NULL_KEY_NAME, NULL_KEY_NAME);
+    }
+
+    /**
+     * Constructor to create a reference key for the given parent concept key with the given local name.
+     *
+     * @param pfConceptKey
+     *        the parent concept key of this reference key
+     * @param localName
+     *        the local name of this reference key
+     */
+    public PfReferenceKey(final PfConceptKey pfConceptKey, final String localName) {
+        this(pfConceptKey, NULL_KEY_NAME, localName);
+    }
+
+    /**
+     * Constructor to create a reference key for the given parent reference key with the given local name.
+     *
+     * @param parentReferenceKey
+     *        the parent reference key of this reference key
+     * @param localName
+     *        the local name of this reference key
+     */
+    public PfReferenceKey(final PfReferenceKey parentReferenceKey, final String localName) {
+        this(parentReferenceKey.getParentConceptKey(), parentReferenceKey.getLocalName(), localName);
+    }
+
+    /**
+     * Constructor to create a reference key for the given parent reference key (specified by the parent reference key's
+     * concept key and local name) with the given local name.
+     *
+     * @param pfConceptKey
+     *        the concept key of the parent reference key of this reference key
+     * @param parentLocalName
+     *        the local name of the parent reference key of this reference key
+     * @param localName
+     *        the local name of this reference key
+     */
+    public PfReferenceKey(final PfConceptKey pfConceptKey, final String parentLocalName, final String localName) {
+        this(pfConceptKey.getName(), pfConceptKey.getVersion(), parentLocalName, localName);
+    }
+
+    /**
+     * Constructor to create a reference key for the given parent concept key (specified by the parent concept key's
+     * name and version) with the given local name.
+     *
+     * @param parentKeyName
+     *        the name of the parent concept key of this reference key
+     * @param parentKeyVersion
+     *        the version of the parent concept key of this reference key
+     * @param localName
+     *        the local name of this reference key
+     */
+    public PfReferenceKey(final String parentKeyName, final String parentKeyVersion, final String localName) {
+        this(parentKeyName, parentKeyVersion, NULL_KEY_NAME, localName);
+    }
+
+    /**
+     * Constructor to create a reference key for the given parent key (specified by the parent key's name, version nad
+     * local name) with the given local name.
+     *
+     * @param parentKeyName
+     *        the parent key name of this reference key
+     * @param parentKeyVersion
+     *        the parent key version of this reference key
+     * @param parentLocalName
+     *        the parent local name of this reference key
+     * @param localName
+     *        the local name of this reference key
+     */
+    public PfReferenceKey(final String parentKeyName, final String parentKeyVersion, final String parentLocalName,
+                    final String localName) {
+        super();
+        this.parentKeyName = Assertions.validateStringParameter(PARENT_KEY_NAME, parentKeyName, NAME_REGEXP);
+        this.parentKeyVersion = Assertions.validateStringParameter(PARENT_KEY_VERSION, parentKeyVersion,
+                        VERSION_REGEXP);
+        this.parentLocalName = Assertions.validateStringParameter(PARENT_LOCAL_NAME, parentLocalName,
+                        LOCAL_NAME_REGEXP);
+        this.localName = Assertions.validateStringParameter(LOCAL_NAME, localName, LOCAL_NAME_REGEXP);
+    }
+
+    /**
+     * Constructor to create a key from the specified key ID.
+     *
+     * @param id
+     *        the key ID in a format that respects the KEY_ID_REGEXP
+     */
+    public PfReferenceKey(final String id) {
+        final String conditionedId = Assertions.validateStringParameter("id", id, REFERENCE_KEY_ID_REGEXP);
+
+        // Split on colon, if the id passes the regular expression test above
+        // it'll have just three colons separating the parent name,
+        // parent version, parent local name, and and local name
+        // No need for range checks or size checks on the array
+        final String[] nameVersionNameArray = conditionedId.split(":");
+
+        // Initiate the new key
+        parentKeyName = Assertions.validateStringParameter(PARENT_KEY_NAME, nameVersionNameArray[PARENT_NAME_FIELD],
+                        NAME_REGEXP);
+        parentKeyVersion = Assertions.validateStringParameter(PARENT_KEY_VERSION,
+                        nameVersionNameArray[PARENT_VERSION_FIELD], VERSION_REGEXP);
+        parentLocalName = Assertions.validateStringParameter(PARENT_LOCAL_NAME,
+                        nameVersionNameArray[PARENT_LOCAL_NAME_FIELD], LOCAL_NAME_REGEXP);
+        localName = Assertions.validateStringParameter(LOCAL_NAME, nameVersionNameArray[LOCAL_NAME_FIELD],
+                        LOCAL_NAME_REGEXP);
+    }
+
+    /**
+     * Get a null reference key.
+     *
+     * @return a null reference key
+     */
+    public static PfReferenceKey getNullKey() {
+        return new PfReferenceKey(PfKey.NULL_KEY_NAME, PfKey.NULL_KEY_VERSION, PfKey.NULL_KEY_NAME,
+                        PfKey.NULL_KEY_NAME);
+    }
+
+    @Override
+    public PfReferenceKey getKey() {
+        return this;
+    }
+
+    @Override
+    public List<PfKey> getKeys() {
+        final List<PfKey> keyList = new ArrayList<>();
+        keyList.add(getKey());
+        return keyList;
+    }
+
+    @Override
+    public String getId() {
+        return parentKeyName + ':' + parentKeyVersion + ':' + parentLocalName + ':' + localName;
+    }
+
+    /**
+     * Gets the parent concept key of this reference key.
+     *
+     * @return the parent concept key of this reference key
+     */
+    public PfConceptKey getParentConceptKey() {
+        return new PfConceptKey(parentKeyName, parentKeyVersion);
+    }
+
+    /**
+     * Gets the parent reference key of this reference key.
+     *
+     * @return the parent reference key of this reference key
+     */
+    public PfReferenceKey getParentReferenceKey() {
+        return new PfReferenceKey(parentKeyName, parentKeyVersion, parentLocalName);
+    }
+
+    /**
+     * Sets the parent concept key of this reference key.
+     *
+     * @param parentKey
+     *        the parent concept key of this reference key
+     */
+    public void setParentConceptKey(final PfConceptKey parentKey) {
+        Assertions.argumentNotNull(parentKey, "parentKey may not be null");
+
+        parentKeyName = parentKey.getName();
+        parentKeyVersion = parentKey.getVersion();
+        parentLocalName = NULL_KEY_NAME;
+    }
+
+    /**
+     * Sets the parent reference key of this reference key.
+     *
+     * @param parentKey
+     *        the parent reference key of this reference key
+     */
+    public void setParentReferenceKey(final PfReferenceKey parentKey) {
+        Assertions.argumentNotNull(parentKey, "parentKey may not be null");
+
+        parentKeyName = parentKey.getParentKeyName();
+        parentKeyVersion = parentKey.getParentKeyVersion();
+        parentLocalName = parentKey.getLocalName();
+    }
+
+    @Override
+    public PfKey.Compatibility getCompatibility(final PfKey otherKey) {
+        if (!(otherKey instanceof PfReferenceKey)) {
+            return Compatibility.DIFFERENT;
+        }
+        final PfReferenceKey otherReferenceKey = (PfReferenceKey) otherKey;
+
+        return this.getParentConceptKey().getCompatibility(otherReferenceKey.getParentConceptKey());
+    }
+
+    @Override
+    public boolean isCompatible(final PfKey otherKey) {
+        if (!(otherKey instanceof PfReferenceKey)) {
+            return false;
+        }
+        final PfReferenceKey otherReferenceKey = (PfReferenceKey) otherKey;
+
+        return this.getParentConceptKey().isCompatible(otherReferenceKey.getParentConceptKey());
+    }
+
+    @Override
+    public PfValidationResult validate(final PfValidationResult result) {
+        final String parentNameValidationErrorMessage = Assertions.getStringParameterValidationMessage(PARENT_KEY_NAME,
+                        parentKeyName, NAME_REGEXP);
+        if (parentNameValidationErrorMessage != null) {
+            result.addValidationMessage(new PfValidationMessage(this, this.getClass(), ValidationResult.INVALID,
+                            "parentKeyName invalid-" + parentNameValidationErrorMessage));
+        }
+
+        final String parentKeyVersionValidationErrorMessage = Assertions
+                        .getStringParameterValidationMessage(PARENT_KEY_VERSION, parentKeyVersion, VERSION_REGEXP);
+        if (parentKeyVersionValidationErrorMessage != null) {
+            result.addValidationMessage(new PfValidationMessage(this, this.getClass(), ValidationResult.INVALID,
+                            "parentKeyVersion invalid-" + parentKeyVersionValidationErrorMessage));
+        }
+
+        final String parentLocalNameValidationErrorMessage = Assertions
+                        .getStringParameterValidationMessage(PARENT_LOCAL_NAME, parentLocalName, LOCAL_NAME_REGEXP);
+        if (parentLocalNameValidationErrorMessage != null) {
+            result.addValidationMessage(new PfValidationMessage(this, this.getClass(), ValidationResult.INVALID,
+                            "parentLocalName invalid-" + parentLocalNameValidationErrorMessage));
+        }
+
+        final String localNameValidationErrorMessage = Assertions.getStringParameterValidationMessage(LOCAL_NAME,
+                        localName, LOCAL_NAME_REGEXP);
+        if (localNameValidationErrorMessage != null) {
+            result.addValidationMessage(new PfValidationMessage(this, this.getClass(), ValidationResult.INVALID,
+                            "localName invalid-" + localNameValidationErrorMessage));
+        }
+
+        return result;
+    }
+
+    @Override
+    public void clean() {
+        parentKeyName = Assertions.validateStringParameter(PARENT_KEY_NAME, parentKeyName, NAME_REGEXP);
+        parentKeyVersion = Assertions.validateStringParameter(PARENT_KEY_VERSION, parentKeyVersion, VERSION_REGEXP);
+        parentLocalName = Assertions.validateStringParameter(PARENT_LOCAL_NAME, parentLocalName, LOCAL_NAME_REGEXP);
+        localName = Assertions.validateStringParameter(LOCAL_NAME, localName, LOCAL_NAME_REGEXP);
+    }
+
+    @Override
+    public PfConcept copyTo(final PfConcept target) {
+        Assertions.argumentNotNull(target, "target may not be null");
+
+        final Object copyObject = target;
+        Assertions.instanceOf(copyObject, PfReferenceKey.class);
+
+        final PfReferenceKey copy = ((PfReferenceKey) copyObject);
+        copy.setParentKeyName(parentKeyName);
+        copy.setParentKeyVersion(parentKeyVersion);
+        copy.setLocalName(localName);
+        copy.setParentLocalName(parentLocalName);
+
+        return copy;
+    }
+
+    @Override
+    public int compareTo(final PfConcept otherObj) {
+        Assertions.argumentNotNull(otherObj, "comparison object may not be null");
+
+        if (this == otherObj) {
+            return 0;
+        }
+        if (getClass() != otherObj.getClass()) {
+            return this.hashCode() - otherObj.hashCode();
+        }
+
+        final PfReferenceKey other = (PfReferenceKey) otherObj;
+        if (!parentKeyName.equals(other.parentKeyName)) {
+            return parentKeyName.compareTo(other.parentKeyName);
+        }
+        if (!parentKeyVersion.equals(other.parentKeyVersion)) {
+            return parentKeyVersion.compareTo(other.parentKeyVersion);
+        }
+        if (!parentLocalName.equals(other.parentLocalName)) {
+            return parentLocalName.compareTo(other.parentLocalName);
+        }
+        return localName.compareTo(other.localName);
+    }
+}
diff --git a/models-base/src/test/java/org/onap/policy/models/base/ExceptionsTest.java b/models-base/src/test/java/org/onap/policy/models/base/ExceptionsTest.java
index 92e928e..c0898c1 100644
--- a/models-base/src/test/java/org/onap/policy/models/base/ExceptionsTest.java
+++ b/models-base/src/test/java/org/onap/policy/models/base/ExceptionsTest.java
@@ -1,4 +1,4 @@
-/*
+/*-
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2019 Nordix Foundation.
  * ================================================================================
diff --git a/models-base/src/test/java/org/onap/policy/models/base/PfConceptGetterImplTest.java b/models-base/src/test/java/org/onap/policy/models/base/PfConceptGetterImplTest.java
new file mode 100644
index 0000000..0a5ccdc
--- /dev/null
+++ b/models-base/src/test/java/org/onap/policy/models/base/PfConceptGetterImplTest.java
@@ -0,0 +1,96 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.models.base;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+import java.util.NavigableMap;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import org.junit.Test;
+
+/**
+ * Test the AxConceptGetterImpl class.
+ */
+public class PfConceptGetterImplTest {
+
+    @Test
+    public void testAxConceptGetterImpl() {
+        NavigableMap<PfConceptKey, PfConceptKey> keyMap = new TreeMap<>();
+
+        PfConceptGetterImpl<PfConceptKey> getter = new PfConceptGetterImpl<>(keyMap);
+        assertNotNull(getter);
+
+        PfConceptKey keyA = new PfConceptKey("A", "0.0.1");
+        assertNull(getter.get(keyA));
+
+        try {
+            getter.get((String)null);
+            fail("test should throw an exception here");
+        }
+        catch (Exception getException) {
+            assertEquals("conceptKeyName may not be null", getException.getMessage());
+        }
+
+        assertNull(getter.get("W"));
+
+        PfConceptKey keyZ = new PfConceptKey("Z", "0.0.1");
+        keyMap.put(keyZ, keyZ);
+        assertNull(getter.get("W"));
+
+        PfConceptKey keyW001 = new PfConceptKey("W", "0.0.1");
+        keyMap.put(keyW001, keyW001);
+        assertEquals(keyW001, getter.get("W"));
+
+        PfConceptKey keyW002 = new PfConceptKey("W", "0.0.2");
+        keyMap.put(keyW002, keyW002);
+        assertEquals(keyW002, getter.get("W"));
+
+        keyMap.remove(keyZ);
+        assertEquals(keyW002, getter.get("W"));
+
+        try {
+            getter.get((String)null, "0.0.1");
+            fail("test should throw an exception here");
+        }
+        catch (Exception getException) {
+            assertEquals("conceptKeyName may not be null", getException.getMessage());
+        }
+
+        assertEquals(keyW002, getter.get("W", "0.0.2"));
+        assertEquals(keyW002, getter.get("W", (String)null));
+
+        assertEquals(new TreeSet<PfConceptKey>(keyMap.values()), getter.getAll(null));
+        assertEquals(new TreeSet<PfConceptKey>(keyMap.values()), getter.getAll(null, null));
+
+        assertEquals(keyW001, getter.getAll("W", null).iterator().next());
+        assertEquals(keyW002, getter.getAll("W", "0.0.2").iterator().next());
+        assertEquals(0, getter.getAll("A", null).size());
+        assertEquals(0, getter.getAll("Z", null).size());
+
+        keyMap.put(keyZ, keyZ);
+        assertEquals(keyW002, getter.getAll("W", "0.0.2").iterator().next());
+    }
+}
diff --git a/models-base/src/test/java/org/onap/policy/models/base/PfKeyTest.java b/models-base/src/test/java/org/onap/policy/models/base/PfKeyTest.java
index dd28f33..1ffc5d2 100644
--- a/models-base/src/test/java/org/onap/policy/models/base/PfKeyTest.java
+++ b/models-base/src/test/java/org/onap/policy/models/base/PfKeyTest.java
@@ -1,4 +1,4 @@
-/*
+/*-
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2019 Nordix Foundation.
  * ================================================================================
@@ -37,7 +37,7 @@
 public class PfKeyTest {
 
     @Test
-    public void testArtifactKey() {
+    public void testConceptKey() {
         try {
             new PfConceptKey("some bad key id");
             fail("This test should throw an exception");
@@ -113,7 +113,7 @@
         assertNotNull(someKey0.toString());
 
         PfConceptKey someKey7 = new PfConceptKey(someKey1);
-        assertEquals(150332875, someKey7.hashCode());
+        assertEquals(244799191, someKey7.hashCode());
         assertEquals(0, someKey7.compareTo(someKey1));
         assertEquals(-12, someKey7.compareTo(someKey0));
 
@@ -124,7 +124,7 @@
         }
 
         assertEquals(0, someKey0.compareTo(someKey0));
-        assertEquals(161539407, someKey0.compareTo(new DummyPfKey()));
+        assertEquals(266127751, someKey0.compareTo(new DummyPfKey()));
 
         assertFalse(someKey0.equals(null));
         assertTrue(someKey0.equals(someKey0));
diff --git a/models-base/src/test/java/org/onap/policy/models/base/PfKeyUseTest.java b/models-base/src/test/java/org/onap/policy/models/base/PfKeyUseTest.java
new file mode 100644
index 0000000..7dbde74
--- /dev/null
+++ b/models-base/src/test/java/org/onap/policy/models/base/PfKeyUseTest.java
@@ -0,0 +1,78 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.models.base;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.onap.policy.models.base.PfKey.Compatibility;
+
+public class PfKeyUseTest {
+
+    @Test
+    public void test() {
+        assertNotNull(new PfKeyUse());
+        assertNotNull(new PfKeyUse(new PfConceptKey()));
+        assertNotNull(new PfKeyUse(new PfReferenceKey()));
+
+        PfConceptKey key = new PfConceptKey("Key", "0.0.1");
+        PfKeyUse keyUse = new PfKeyUse();
+        keyUse.setKey(key);
+        assertEquals(key, keyUse.getKey());
+        assertEquals("Key:0.0.1", keyUse.getId());
+        assertEquals(key, keyUse.getKeys().get(0));
+
+        assertEquals(Compatibility.IDENTICAL, keyUse.getCompatibility(key));
+        assertTrue(keyUse.isCompatible(key));
+
+        keyUse.clean();
+        assertNotNull(keyUse);
+
+        PfValidationResult result = new PfValidationResult();
+        result = keyUse.validate(result);
+        assertNotNull(result);
+
+        assertNotEquals(0, keyUse.hashCode());
+
+        PfKeyUse clonedKeyUse = new PfKeyUse(keyUse);
+        assertEquals("PfKeyUse(usedKey=PfConceptKey(name=Key, version=0.0.1))", clonedKeyUse.toString());
+
+        assertFalse(keyUse.hashCode() == 0);
+
+        assertTrue(keyUse.equals(keyUse));
+        assertTrue(keyUse.equals(clonedKeyUse));
+        assertFalse(keyUse.equals("Hello"));
+        assertTrue(keyUse.equals(new PfKeyUse(key)));
+
+        assertEquals(0, keyUse.compareTo(keyUse));
+        assertEquals(0, keyUse.compareTo(clonedKeyUse));
+        assertNotEquals(0, keyUse.compareTo(new PfConceptKey()));
+        assertEquals(0, keyUse.compareTo(new PfKeyUse(key)));
+
+        PfKeyUse keyUseNull = new PfKeyUse(PfConceptKey.getNullKey());
+        PfValidationResult resultNull = new PfValidationResult();
+        assertEquals(false, keyUseNull.validate(resultNull).isValid());
+    }
+}
diff --git a/models-base/src/test/java/org/onap/policy/models/base/PfReferenceKeyTest.java b/models-base/src/test/java/org/onap/policy/models/base/PfReferenceKeyTest.java
new file mode 100644
index 0000000..feedc2c
--- /dev/null
+++ b/models-base/src/test/java/org/onap/policy/models/base/PfReferenceKeyTest.java
@@ -0,0 +1,198 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.models.base;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+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.lang.reflect.Field;
+
+import org.junit.Test;
+
+public class PfReferenceKeyTest {
+
+    @Test
+    public void testPfReferenceKey() {
+        assertNotNull(new PfReferenceKey());
+        assertNotNull(new PfReferenceKey(new PfConceptKey()));
+        assertNotNull(new PfReferenceKey(new PfConceptKey(), "LocalName"));
+        assertNotNull(new PfReferenceKey(new PfReferenceKey()));
+        assertNotNull(new PfReferenceKey(new PfReferenceKey(), "LocalName"));
+        assertNotNull(new PfReferenceKey(new PfConceptKey(), "ParentLocalName", "LocalName"));
+        assertNotNull(new PfReferenceKey("ParentKeyName", "0.0.1", "LocalName"));
+        assertNotNull(new PfReferenceKey("ParentKeyName", "0.0.1", "ParentLocalName", "LocalName"));
+        assertNotNull(new PfReferenceKey("ParentKeyName:0.0.1:ParentLocalName:LocalName"));
+        assertEquals(PfReferenceKey.getNullKey().getKey(), PfReferenceKey.getNullKey());
+        assertEquals("NULL:0.0.0:NULL:NULL", PfReferenceKey.getNullKey().getId());
+
+        PfReferenceKey testReferenceKey = new PfReferenceKey();
+        testReferenceKey.setParentConceptKey(new PfConceptKey("PN", "0.0.1"));
+        assertEquals("PN:0.0.1", testReferenceKey.getParentConceptKey().getId());
+
+        testReferenceKey.setParentReferenceKey(new PfReferenceKey("PN", "0.0.1", "LN"));
+        assertEquals("PN:0.0.1:NULL:LN", testReferenceKey.getParentReferenceKey().getId());
+
+        testReferenceKey.setParentKeyName("NPKN");
+        assertEquals("NPKN", testReferenceKey.getParentKeyName());
+
+        testReferenceKey.setParentKeyVersion("0.0.1");
+        assertEquals("0.0.1", testReferenceKey.getParentKeyVersion());
+
+        testReferenceKey.setParentLocalName("NPKLN");
+        assertEquals("NPKLN", testReferenceKey.getParentLocalName());
+
+        testReferenceKey.setLocalName("NLN");
+        assertEquals("NLN", testReferenceKey.getLocalName());
+
+        assertFalse(testReferenceKey.isCompatible(PfConceptKey.getNullKey()));
+        assertFalse(testReferenceKey.isCompatible(PfReferenceKey.getNullKey()));
+        assertTrue(testReferenceKey.isCompatible(testReferenceKey));
+
+        assertEquals(PfKey.Compatibility.DIFFERENT, testReferenceKey.getCompatibility(PfConceptKey.getNullKey()));
+        assertEquals(PfKey.Compatibility.DIFFERENT, testReferenceKey.getCompatibility(PfReferenceKey.getNullKey()));
+        assertEquals(PfKey.Compatibility.IDENTICAL, testReferenceKey.getCompatibility(testReferenceKey));
+
+        PfValidationResult result = new PfValidationResult();
+        result = testReferenceKey.validate(result);
+        assertEquals(PfValidationResult.ValidationResult.VALID, result.getValidationResult());
+
+        testReferenceKey.clean();
+
+        PfReferenceKey clonedReferenceKey = new PfReferenceKey(testReferenceKey);
+        assertEquals("PfReferenceKey(parentKeyName=NPKN, parentKeyVersion=0.0.1, parentLocalName=NPKLN, localName=NLN)",
+                clonedReferenceKey.toString());
+
+        assertFalse(testReferenceKey.hashCode() == 0);
+
+        assertTrue(testReferenceKey.equals(testReferenceKey));
+        assertTrue(testReferenceKey.equals(clonedReferenceKey));
+        assertFalse(testReferenceKey.equals("Hello"));
+        assertFalse(testReferenceKey.equals(new PfReferenceKey("PKN", "0.0.2", "PLN", "LN")));
+        assertFalse(testReferenceKey.equals(new PfReferenceKey("NPKN", "0.0.2", "PLN", "LN")));
+        assertFalse(testReferenceKey.equals(new PfReferenceKey("NPKN", "0.0.1", "PLN", "LN")));
+        assertFalse(testReferenceKey.equals(new PfReferenceKey("NPKN", "0.0.1", "NPLN", "LN")));
+        assertTrue(testReferenceKey.equals(new PfReferenceKey("NPKN", "0.0.1", "NPKLN", "NLN")));
+
+        assertEquals(0, testReferenceKey.compareTo(testReferenceKey));
+        assertEquals(0, testReferenceKey.compareTo(clonedReferenceKey));
+        assertNotEquals(0, testReferenceKey.compareTo(new PfConceptKey()));
+        assertNotEquals(0, testReferenceKey.compareTo(new PfReferenceKey("PKN", "0.0.2", "PLN", "LN")));
+        assertNotEquals(0, testReferenceKey.compareTo(new PfReferenceKey("NPKN", "0.0.2", "PLN", "LN")));
+        assertNotEquals(0, testReferenceKey.compareTo(new PfReferenceKey("NPKN", "0.0.1", "PLN", "LN")));
+        assertNotEquals(0, testReferenceKey.compareTo(new PfReferenceKey("NPKN", "0.0.1", "NPLN", "LN")));
+        assertEquals(0, testReferenceKey.compareTo(new PfReferenceKey("NPKN", "0.0.1", "NPKLN", "NLN")));
+
+        assertFalse(testReferenceKey.equals(null));
+
+        try {
+            testReferenceKey.copyTo(null);
+            fail("test should throw an exception here");
+        } catch (Exception iae) {
+            assertEquals("target may not be null", iae.getMessage());
+        }
+
+        try {
+            testReferenceKey.copyTo(new PfConceptKey("Key", "0.0.1"));
+            fail("test should throw an exception here");
+        } catch (Exception iae) {
+            assertEquals("org.onap.policy.models.base.PfConceptKey"
+                    + " is not an instance of org.onap.policy.models.base.PfReferenceKey", iae.getMessage());
+        }
+
+        PfReferenceKey targetRefKey = new PfReferenceKey();
+        assertEquals(testReferenceKey, testReferenceKey.copyTo(targetRefKey));
+    }
+
+    @Test
+    public void testValidation() {
+        PfReferenceKey testReferenceKey = new PfReferenceKey();
+        testReferenceKey.setParentConceptKey(new PfConceptKey("PN", "0.0.1"));
+        assertEquals("PN:0.0.1", testReferenceKey.getParentConceptKey().getId());
+
+        try {
+            Field parentNameField = testReferenceKey.getClass().getDeclaredField("parentKeyName");
+            parentNameField.setAccessible(true);
+            parentNameField.set(testReferenceKey, "Parent Name");
+            PfValidationResult validationResult = new PfValidationResult();
+            testReferenceKey.validate(validationResult);
+            parentNameField.set(testReferenceKey, "ParentName");
+            parentNameField.setAccessible(false);
+            assertEquals(
+                    "parentKeyName invalid-parameter parentKeyName with value Parent Name "
+                            + "does not match regular expression [A-Za-z0-9\\-_\\.]+",
+                    validationResult.getMessageList().get(0).getMessage());
+        } catch (Exception validationException) {
+            fail("test should not throw an exception");
+        }
+
+        try {
+            Field parentVersionField = testReferenceKey.getClass().getDeclaredField("parentKeyVersion");
+            parentVersionField.setAccessible(true);
+            parentVersionField.set(testReferenceKey, "Parent Version");
+            PfValidationResult validationResult = new PfValidationResult();
+            testReferenceKey.validate(validationResult);
+            parentVersionField.set(testReferenceKey, "0.0.1");
+            parentVersionField.setAccessible(false);
+            assertEquals(
+                    "parentKeyVersion invalid-parameter parentKeyVersion with value Parent Version "
+                            + "does not match regular expression [A-Za-z0-9.]+",
+                    validationResult.getMessageList().get(0).getMessage());
+        } catch (Exception validationException) {
+            fail("test should not throw an exception");
+        }
+
+        try {
+            Field parentLocalNameField = testReferenceKey.getClass().getDeclaredField("parentLocalName");
+            parentLocalNameField.setAccessible(true);
+            parentLocalNameField.set(testReferenceKey, "Parent Local Name");
+            PfValidationResult validationResult = new PfValidationResult();
+            testReferenceKey.validate(validationResult);
+            parentLocalNameField.set(testReferenceKey, "ParentLocalName");
+            parentLocalNameField.setAccessible(false);
+            assertEquals(
+                    "parentLocalName invalid-parameter parentLocalName with value "
+                            + "Parent Local Name does not match regular expression [A-Za-z0-9\\-_\\.]+|^$",
+                    validationResult.getMessageList().get(0).getMessage());
+        } catch (Exception validationException) {
+            fail("test should not throw an exception");
+        }
+
+        try {
+            Field localNameField = testReferenceKey.getClass().getDeclaredField("localName");
+            localNameField.setAccessible(true);
+            localNameField.set(testReferenceKey, "Local Name");
+            PfValidationResult validationResult = new PfValidationResult();
+            testReferenceKey.validate(validationResult);
+            localNameField.set(testReferenceKey, "LocalName");
+            localNameField.setAccessible(false);
+            assertEquals(
+                    "localName invalid-parameter localName with value Local Name "
+                            + "does not match regular expression [A-Za-z0-9\\-_\\.]+|^$",
+                    validationResult.getMessageList().get(0).getMessage());
+        } catch (Exception validationException) {
+            fail("test should not throw an exception");
+        }
+    }
+}
diff --git a/models-base/src/test/java/org/onap/policy/models/base/ValidationTest.java b/models-base/src/test/java/org/onap/policy/models/base/ValidationTest.java
index 385039c..0d4f2a7 100644
--- a/models-base/src/test/java/org/onap/policy/models/base/ValidationTest.java
+++ b/models-base/src/test/java/org/onap/policy/models/base/ValidationTest.java
@@ -1,4 +1,4 @@
-/*
+/*-
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2019 Nordix Foundation.
  * ================================================================================
diff --git a/models-base/src/test/java/org/onap/policy/models/base/testpojos/DummyPfConcept.java b/models-base/src/test/java/org/onap/policy/models/base/testpojos/DummyPfConcept.java
index 85727f4..f28477f 100644
--- a/models-base/src/test/java/org/onap/policy/models/base/testpojos/DummyPfConcept.java
+++ b/models-base/src/test/java/org/onap/policy/models/base/testpojos/DummyPfConcept.java
@@ -20,6 +20,7 @@
 
 package org.onap.policy.models.base.testpojos;
 
+import java.util.Arrays;
 import java.util.List;
 
 import org.onap.policy.models.base.PfConcept;
@@ -42,7 +43,7 @@
 
     @Override
     public List<PfKey> getKeys() {
-        return null;
+        return Arrays.asList(getKey());
     }
 
     @Override
diff --git a/models-base/src/test/java/org/onap/policy/models/base/testpojos/DummyPfKey.java b/models-base/src/test/java/org/onap/policy/models/base/testpojos/DummyPfKey.java
index 19358a1..247ea88 100644
--- a/models-base/src/test/java/org/onap/policy/models/base/testpojos/DummyPfKey.java
+++ b/models-base/src/test/java/org/onap/policy/models/base/testpojos/DummyPfKey.java
@@ -20,6 +20,7 @@
 
 package org.onap.policy.models.base.testpojos;
 
+import java.util.Arrays;
 import java.util.List;
 
 import org.onap.policy.models.base.PfConcept;
@@ -56,7 +57,7 @@
 
     @Override
     public List<PfKey> getKeys() {
-        return null;
+        return Arrays.asList(getKey());
     }
 
     @Override
diff --git a/models-dao/pom.xml b/models-dao/pom.xml
index 90b9801..d71fce8 100644
--- a/models-dao/pom.xml
+++ b/models-dao/pom.xml
@@ -30,4 +30,19 @@
     <artifactId>policy-models-dao</artifactId>
     <name>${project.artifactId}</name>
     <description>[${project.parent.artifactId}] module provides common DAO (Data Access Object) model handling for the ONAP Policy Framework</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.onap.policy.models</groupId>
+            <artifactId>policy-models-base</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.h2database</groupId>
+            <artifactId>h2</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+    </dependencies>
 </project>
diff --git a/models-dao/src/main/java/org/onap/policy/models/dao/DaoParameters.java b/models-dao/src/main/java/org/onap/policy/models/dao/DaoParameters.java
new file mode 100644
index 0000000..18ae74a
--- /dev/null
+++ b/models-dao/src/main/java/org/onap/policy/models/dao/DaoParameters.java
@@ -0,0 +1,126 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.models.dao;
+
+import java.util.Properties;
+
+/**
+ * This class is a POJO that holds properties for PF DAOs.
+ */
+public class DaoParameters {
+    /** The default PF DAO plugin class. */
+    public static final String DEFAULT_PLUGIN_CLASS = "org.onap.policy.models.dao.impl.DefaultPfDao";
+
+    private String pluginClass = DEFAULT_PLUGIN_CLASS;
+    private String persistenceUnit;
+
+    private Properties jdbcProperties = new Properties();
+
+    /**
+     * Gets the DAO plugin class, this is the DAO class to use and it must implement the
+     * {@link PfDao} interface.
+     *
+     * @return the DAO plugin class
+     */
+    public String getPluginClass() {
+        return pluginClass;
+    }
+
+    /**
+     * Sets the DAO plugin class, a class that implements the {@link PfDao} interface.
+     *
+     * @param daoPluginClass the DAO plugin class
+     */
+    public void setPluginClass(final String daoPluginClass) {
+        pluginClass = daoPluginClass;
+    }
+
+    /**
+     * Gets the persistence unit for the DAO. The persistence unit defines the JDBC properties the
+     * DAO will use. The persistence unit must defined in the {@code META-INF/persistence.xml}
+     * resource file
+     *
+     * @return the persistence unit to use for JDBC access
+     */
+    public String getPersistenceUnit() {
+        return persistenceUnit;
+    }
+
+    /**
+     * Sets the persistence unit for the DAO. The persistence unit defines the JDBC properties the
+     * DAO will use. The persistence unit must defined in the {@code META-INF/persistence.xml}
+     * resource file
+     *
+     * @param daoPersistenceUnit the persistence unit to use for JDBC access
+     */
+    public void setPersistenceUnit(final String daoPersistenceUnit) {
+        persistenceUnit = daoPersistenceUnit;
+    }
+
+    /**
+     * Gets the JDBC properties.
+     *
+     * @return the JDBC properties
+     */
+    public Properties getJdbcProperties() {
+        return jdbcProperties;
+    }
+
+    /**
+     * Sets the JDBC properties.
+     *
+     * @param jdbcProperties the JDBC properties
+     */
+    public void setJdbcProperties(final Properties jdbcProperties) {
+        this.jdbcProperties = jdbcProperties;
+    }
+
+    /**
+     * Gets a single JDBC property.
+     *
+     * @param key the key of the property
+     * @return the JDBC property
+     */
+    public String getJdbcProperty(final String key) {
+        return jdbcProperties.getProperty(key);
+    }
+
+    /**
+     * Sets a single JDBC property.
+     *
+     * @param key the key of the property
+     * @param value the value of the JDBC property
+     */
+    public void setJdbcProperty(final String key, final String value) {
+        jdbcProperties.setProperty(key, value);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return "DAOParameters [pluginClass=" + pluginClass + ", persistenceUnit=" + persistenceUnit
+                + ", jdbcProperties=" + jdbcProperties + "]";
+    }
+}
diff --git a/models-dao/src/main/java/org/onap/policy/models/dao/PfDao.java b/models-dao/src/main/java/org/onap/policy/models/dao/PfDao.java
new file mode 100644
index 0000000..85c971c
--- /dev/null
+++ b/models-dao/src/main/java/org/onap/policy/models/dao/PfDao.java
@@ -0,0 +1,205 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.models.dao;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.onap.policy.models.base.PfConcept;
+import org.onap.policy.models.base.PfConceptKey;
+import org.onap.policy.models.base.PfModelException;
+import org.onap.policy.models.base.PfReferenceKey;
+
+/**
+ * The Interface PfDao describes the DAO interface for reading and writing Policy Framework
+ * {@link PfConcept} concepts to and from databases using JDBC.
+ */
+public interface PfDao {
+
+    /**
+     * Initialize the Policy Framework DAO with the given parameters.
+     *
+     * @param daoParameters parameters to use to access the database
+     * @throws PfModelException on initialization errors
+     */
+    void init(DaoParameters daoParameters) throws PfModelException;
+
+    /**
+     * Close the Policy Framework DAO.
+     */
+    void close();
+
+    /**
+     * Creates an Policy Framework concept on the database.
+     *
+     * @param <T> the type of the object to create, a subclass of {@link PfConcept}
+     * @param obj the object to create
+     */
+    <T extends PfConcept> void create(T obj);
+
+    /**
+     * Delete an Policy Framework concept on the database.
+     *
+     * @param <T> the type of the object to delete, a subclass of {@link PfConcept}
+     * @param obj the object to delete
+     */
+    <T extends PfConcept> void delete(T obj);
+
+    /**
+     * Delete an Policy Framework concept on the database.
+     *
+     * @param <T> the type of the object to delete, a subclass of {@link PfConcept}
+     * @param someClass the class of the object to delete, a subclass of {@link PfConcept}
+     * @param key the key of the object to delete
+     */
+    <T extends PfConcept> void delete(Class<T> someClass, PfConceptKey key);
+
+    /**
+     * Delete an Policy Framework concept on the database.
+     *
+     * @param <T> the type of the object to delete, a subclass of {@link PfConcept}
+     * @param someClass the class of the object to delete, a subclass of {@link PfConcept}
+     * @param key the key of the object to delete
+     */
+    <T extends PfConcept> void delete(Class<T> someClass, PfReferenceKey key);
+
+    /**
+     * Create a collection of objects in the database.
+     *
+     * @param <T> the type of the object to create, a subclass of {@link PfConcept}
+     * @param objs the objects to create
+     */
+    <T extends PfConcept> void createCollection(Collection<T> objs);
+
+    /**
+     * Delete a collection of objects in the database.
+     *
+     * @param <T> the type of the objects to delete, a subclass of {@link PfConcept}
+     * @param objs the objects to delete
+     */
+    <T extends PfConcept> void deleteCollection(Collection<T> objs);
+
+    /**
+     * Delete a collection of objects in the database referred to by concept key.
+     *
+     * @param <T> the type of the objects to delete, a subclass of {@link PfConcept}
+     * @param someClass the class of the objects to delete, a subclass of {@link PfConcept}
+     * @param keys the keys of the objects to delete
+     * @return the number of objects deleted
+     */
+    <T extends PfConcept> int deleteByConceptKey(Class<T> someClass, Collection<PfConceptKey> keys);
+
+    /**
+     * Delete a collection of objects in the database referred to by reference key.
+     *
+     * @param <T> the type of the objects to delete, a subclass of {@link PfConcept}
+     * @param someClass the class of the objects to delete, a subclass of {@link PfConcept}
+     * @param keys the keys of the objects to delete
+     * @return the number of objects deleted
+     */
+    <T extends PfConcept> int deleteByReferenceKey(Class<T> someClass, Collection<PfReferenceKey> keys);
+
+    /**
+     * Delete all objects of a given class in the database.
+     *
+     * @param <T> the type of the objects to delete, a subclass of {@link PfConcept}
+     * @param someClass the class of the objects to delete, a subclass of {@link PfConcept}
+     */
+    <T extends PfConcept> void deleteAll(Class<T> someClass);
+
+    /**
+     * Get an object from the database, referred to by concept key.
+     *
+     * @param <T> the type of the object to get, a subclass of {@link PfConcept}
+     * @param someClass the class of the object to get, a subclass of {@link PfConcept}
+     * @param key the key of the object to get
+     * @return the object that was retrieved from the database
+     */
+    <T extends PfConcept> T get(Class<T> someClass, PfConceptKey key);
+
+    /**
+     * Get an object from the database, referred to by reference key.
+     *
+     * @param <T> the type of the object to get, a subclass of {@link PfConcept}
+     * @param someClass the class of the object to get, a subclass of {@link PfConcept}
+     * @param key the key of the object to get
+     * @return the object that was retrieved from the database or null if the object was not
+     *         retrieved
+     */
+    <T extends PfConcept> T get(Class<T> someClass, PfReferenceKey key);
+
+    /**
+     * Get all the objects in the database of a given type.
+     *
+     * @param <T> the type of the objects to get, a subclass of {@link PfConcept}
+     * @param someClass the class of the objects to get, a subclass of {@link PfConcept}
+     * @return the objects or null if no objects were retrieved
+     */
+    <T extends PfConcept> List<T> getAll(Class<T> someClass);
+
+    /**
+     * Get all the objects in the database of the given type with the given parent concept key.
+     *
+     * @param <T> the type of the objects to get, a subclass of {@link PfConcept}
+     * @param someClass the class of the objects to get, a subclass of {@link PfConcept}
+     * @param parentKey the parent key of the concepts to get
+     * @return the all
+     */
+    <T extends PfConcept> List<T> getAll(Class<T> someClass, PfConceptKey parentKey);
+
+    /**
+     * Get a concept from the database with the given concept key.
+     *
+     * @param <T> the type of the object to get, a subclass of {@link PfConcept}
+     * @param someClass the class of the object to get, a subclass of {@link PfConcept}
+     * @param conceptId the concept key of the concept to get
+     * @return the concept that matches the key or null if the concept is not retrieved
+     */
+    <T extends PfConcept> T getConcept(Class<T> someClass, PfConceptKey conceptId);
+
+    /**
+     * Get a concept from the database with the given reference key.
+     *
+     * @param <T> the type of the object to get, a subclass of {@link PfConcept}
+     * @param someClass the class of the object to get, a subclass of {@link PfConcept}
+     * @param conceptId the concept key of the concept to get
+     * @return the concept that matches the key or null if the concept is not retrieved
+     */
+    <T extends PfConcept> T getConcept(Class<T> someClass, PfReferenceKey conceptId);
+
+    /**
+     * Get the number of instances of a concept that exist in the database.
+     *
+     * @param <T> the type of the object to get, a subclass of {@link PfConcept}
+     * @param someClass the class of the object to get, a subclass of {@link PfConcept}
+     * @return the number of instances of the concept in the database
+     */
+    <T extends PfConcept> long size(Class<T> someClass);
+
+    /**
+     * Update a concept in the database.
+     *
+     * @param <T> the type of the object to get, a subclass of {@link PfConcept}
+     * @param obj the object to update
+     * @return the updated object
+     */
+    <T extends PfConcept> T update(T obj);
+}
diff --git a/models-dao/src/main/java/org/onap/policy/models/dao/PfDaoFactory.java b/models-dao/src/main/java/org/onap/policy/models/dao/PfDaoFactory.java
new file mode 100644
index 0000000..3b7e31e
--- /dev/null
+++ b/models-dao/src/main/java/org/onap/policy/models/dao/PfDaoFactory.java
@@ -0,0 +1,68 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.models.dao;
+
+import org.onap.policy.common.utils.validation.Assertions;
+import org.onap.policy.models.base.PfModelException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This factory class returns a Policy Framework DAO for the configured persistence mechanism. The
+ * factory uses the plugin class specified in {@link DaoParameters} to instantiate a DAO instance.
+ */
+public class PfDaoFactory {
+    // Get a reference to the logger
+    private static final Logger LOGGER = LoggerFactory.getLogger(PfDaoFactory.class);
+
+    /**
+     * Return a Policy Framework DAO for the required Policy Framework DAO plugin class.
+     *
+     * @param daoParameters parameters to use to read the database configuration information
+     * @return the Policy Framework DAO
+     * @throws PfModelException on invalid JPA plugins
+     */
+    public PfDao createPfDao(final DaoParameters daoParameters) throws PfModelException {
+        Assertions.argumentOfClassNotNull(daoParameters, PfModelException.class,
+                "Parameter \"daoParameters\" may not be null");
+
+        // Get the class for the DAO using reflection
+        Object pfDaoObject = null;
+        try {
+            pfDaoObject = Class.forName(daoParameters.getPluginClass()).newInstance();
+        } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
+            String errorMessage =
+                    "Policy Framework DAO class not found for DAO plugin \"" + daoParameters.getPluginClass() + "\"";
+            LOGGER.error(errorMessage, e);
+            throw new PfModelException(errorMessage, e);
+        }
+
+        // Check the class is a Policy Framework DAO
+        if (!(pfDaoObject instanceof PfDao)) {
+            String errorMessage = "Specified DAO plugin class \"" + daoParameters.getPluginClass()
+                    + "\" does not implement the PfDao interface";
+            LOGGER.error(errorMessage);
+            throw new PfModelException(errorMessage);
+        }
+
+        return (PfDao) pfDaoObject;
+    }
+}
diff --git a/models-dao/src/main/java/org/onap/policy/models/dao/converters/CDataConditioner.java b/models-dao/src/main/java/org/onap/policy/models/dao/converters/CDataConditioner.java
new file mode 100644
index 0000000..327f65e
--- /dev/null
+++ b/models-dao/src/main/java/org/onap/policy/models/dao/converters/CDataConditioner.java
@@ -0,0 +1,69 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.models.dao.converters;
+
+import javax.persistence.AttributeConverter;
+import javax.persistence.Converter;
+import javax.xml.bind.annotation.adapters.XmlAdapter;
+
+/**
+ * The Class CDATAConditioner converts a CDATA String to and from database format by removing spaces
+ * at the ends of lines and platform-specific new line endings.
+ */
+@Converter
+public class CDataConditioner extends XmlAdapter<String, String> implements AttributeConverter<String, String> {
+
+    private static final String NL = "\n";
+
+    @Override
+    public String convertToDatabaseColumn(final String raw) {
+        return clean(raw);
+    }
+
+    @Override
+    public String convertToEntityAttribute(final String db) {
+        return clean(db);
+    }
+
+    @Override
+    public String unmarshal(final String value) throws Exception {
+        return this.convertToEntityAttribute(value);
+    }
+
+    @Override
+    public String marshal(final String value) throws Exception {
+        return this.convertToDatabaseColumn(value);
+    }
+
+    /**
+     * Clean.
+     *
+     * @param in the in
+     * @return the string
+     */
+    public static final String clean(final String in) {
+        if (in == null) {
+            return null;
+        } else {
+            return in.replaceAll("\\s+$", "").replaceAll("\\r?\\n", NL);
+        }
+    }
+}
diff --git a/models-dao/src/main/java/org/onap/policy/models/dao/converters/Uuid2String.java b/models-dao/src/main/java/org/onap/policy/models/dao/converters/Uuid2String.java
new file mode 100644
index 0000000..a2b1c08
--- /dev/null
+++ b/models-dao/src/main/java/org/onap/policy/models/dao/converters/Uuid2String.java
@@ -0,0 +1,60 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.models.dao.converters;
+
+import java.util.UUID;
+
+import javax.persistence.AttributeConverter;
+import javax.persistence.Converter;
+import javax.xml.bind.annotation.adapters.XmlAdapter;
+
+/**
+ * The Class UUIDConverter converts a UUID to and from database format.
+ */
+@Converter
+public class Uuid2String extends XmlAdapter<String, UUID> implements AttributeConverter<UUID, String> {
+
+    @Override
+    public String convertToDatabaseColumn(final UUID uuid) {
+        String returnString;
+        if (uuid == null) {
+            returnString = "";
+        } else {
+            returnString = uuid.toString();
+        }
+        return returnString;
+    }
+
+    @Override
+    public UUID convertToEntityAttribute(final String uuidString) {
+        return UUID.fromString(uuidString);
+    }
+
+    @Override
+    public UUID unmarshal(final String value) throws Exception {
+        return this.convertToEntityAttribute(value);
+    }
+
+    @Override
+    public String marshal(final UUID value) throws Exception {
+        return this.convertToDatabaseColumn(value);
+    }
+}
diff --git a/models-dao/src/main/java/org/onap/policy/models/dao/converters/package-info.java b/models-dao/src/main/java/org/onap/policy/models/dao/converters/package-info.java
new file mode 100644
index 0000000..416eff2
--- /dev/null
+++ b/models-dao/src/main/java/org/onap/policy/models/dao/converters/package-info.java
@@ -0,0 +1,26 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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=========================================================
+ */
+
+/**
+ * Contains converters used by PF EclipseLink marshaling and unmarshaling of
+ * {@link org.onap.policy.models.base.PfConcept} instances to and from files and databases.
+ */
+
+package org.onap.policy.models.dao.converters;
diff --git a/models-dao/src/main/java/org/onap/policy/models/dao/impl/DefaultPfDao.java b/models-dao/src/main/java/org/onap/policy/models/dao/impl/DefaultPfDao.java
new file mode 100644
index 0000000..429632d
--- /dev/null
+++ b/models-dao/src/main/java/org/onap/policy/models/dao/impl/DefaultPfDao.java
@@ -0,0 +1,415 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.models.dao.impl;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+
+import org.onap.policy.models.base.PfConcept;
+import org.onap.policy.models.base.PfConceptKey;
+import org.onap.policy.models.base.PfModelException;
+import org.onap.policy.models.base.PfModelRuntimeException;
+import org.onap.policy.models.base.PfReferenceKey;
+import org.onap.policy.models.dao.DaoParameters;
+import org.onap.policy.models.dao.PfDao;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The Class DefaultPfDao is an JPA implementation of the {@link PfDao} class for Policy Framework
+ * concepts ({@link PfConcept}). It uses the default JPA implementation in the javax
+ * {@link Persistence} class.
+ */
+public class DefaultPfDao implements PfDao {
+    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultPfDao.class);
+
+    private static final String SELECT_C_FROM = "SELECT c FROM ";
+    private static final String AND_C_KEY_LOCAL_NAME = "' AND c.key.localName='";
+    private static final String AND_C_KEY_PARENT_KEY_VERSION = "' AND c.key.parentKeyVersion='";
+    private static final String C_WHERE_C_KEY_PARENT_KEY_NAME = " c WHERE c.key.parentKeyName='";
+    private static final String AND_C_KEY_VERSION = "' AND c.key.version='";
+    private static final String C_WHERE_C_KEY_NAME = " c WHERE c.key.name='";
+    private static final String DELETE_FROM = "DELETE FROM ";
+
+    // Entity manager for JPA
+    private EntityManagerFactory emf = null;
+
+    @Override
+    public void init(final DaoParameters daoParameters) throws PfModelException {
+        if (daoParameters == null || daoParameters.getPersistenceUnit() == null) {
+            LOGGER.error("Policy Framework persistence unit parameter not set");
+            throw new PfModelException("Policy Framework persistence unit parameter not set");
+        }
+
+        LOGGER.debug("Creating Policy Framework persistence unit \"{}\" . . .", daoParameters.getPersistenceUnit());
+        try {
+            emf = Persistence.createEntityManagerFactory(daoParameters.getPersistenceUnit(),
+                    daoParameters.getJdbcProperties());
+        } catch (final Exception ex) {
+            String errorMessage = "Creation of Policy Framework persistence unit \""
+                    + daoParameters.getPersistenceUnit() + "\" failed";
+            LOGGER.warn(errorMessage, ex);
+            throw new PfModelException(errorMessage, ex);
+        }
+        LOGGER.debug("Created Policy Framework persistence unit \"{}\"", daoParameters.getPersistenceUnit());
+    }
+
+    /**
+     * Gets the entity manager for this DAO.
+     *
+     * @return the entity manager
+     */
+    protected final synchronized EntityManager getEntityManager() {
+        if (emf == null) {
+            LOGGER.warn("Policy Framework DAO has not been initialized");
+            throw new PfModelRuntimeException("Policy Framework DAO has not been initialized");
+        }
+
+        return emf.createEntityManager();
+    }
+
+    @Override
+    public final void close() {
+        if (emf != null) {
+            emf.close();
+        }
+    }
+
+    @Override
+    public <T extends PfConcept> void create(final T obj) {
+        if (obj == null) {
+            return;
+        }
+        final EntityManager mg = getEntityManager();
+        try {
+            mg.getTransaction().begin();
+            mg.merge(obj);
+            mg.getTransaction().commit();
+        } finally {
+            mg.close();
+        }
+    }
+
+    @Override
+    public <T extends PfConcept> void delete(final T obj) {
+        if (obj == null) {
+            return;
+        }
+        final EntityManager mg = getEntityManager();
+        try {
+            mg.getTransaction().begin();
+            mg.remove(mg.contains(obj) ? obj : mg.merge(obj));
+            mg.getTransaction().commit();
+        } finally {
+            mg.close();
+        }
+    }
+
+    @Override
+    public <T extends PfConcept> void delete(final Class<T> someClass, final PfConceptKey key) {
+        if (key == null) {
+            return;
+        }
+        final EntityManager mg = getEntityManager();
+        try {
+            mg.getTransaction().begin();
+            mg.createQuery(DELETE_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_NAME + key.getName()
+                    + AND_C_KEY_VERSION + key.getVersion() + "'", someClass).executeUpdate();
+            mg.getTransaction().commit();
+        } finally {
+            mg.close();
+        }
+    }
+
+    @Override
+    public <T extends PfConcept> void delete(final Class<T> someClass, final PfReferenceKey key) {
+        if (key == null) {
+            return;
+        }
+        final EntityManager mg = getEntityManager();
+        try {
+            mg.getTransaction().begin();
+            mg.createQuery(DELETE_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_PARENT_KEY_NAME
+                    + key.getParentKeyName() + AND_C_KEY_PARENT_KEY_VERSION + key.getParentKeyVersion()
+                    + AND_C_KEY_LOCAL_NAME + key.getLocalName() + "'", someClass).executeUpdate();
+            mg.getTransaction().commit();
+        } finally {
+            mg.close();
+        }
+    }
+
+    @Override
+    public <T extends PfConcept> void createCollection(final Collection<T> objs) {
+        if (objs == null || objs.isEmpty()) {
+            return;
+        }
+        final EntityManager mg = getEntityManager();
+        try {
+            mg.getTransaction().begin();
+            for (final T t : objs) {
+                mg.merge(t);
+            }
+            mg.getTransaction().commit();
+        } finally {
+            mg.close();
+        }
+    }
+
+    @Override
+    public <T extends PfConcept> void deleteCollection(final Collection<T> objs) {
+        if (objs == null || objs.isEmpty()) {
+            return;
+        }
+        final EntityManager mg = getEntityManager();
+        try {
+            mg.getTransaction().begin();
+            for (final T t : objs) {
+                mg.remove(mg.contains(t) ? t : mg.merge(t));
+            }
+            mg.getTransaction().commit();
+        } finally {
+            mg.close();
+        }
+    }
+
+    @Override
+    public <T extends PfConcept> int deleteByConceptKey(final Class<T> someClass,
+            final Collection<PfConceptKey> keys) {
+        if (keys == null || keys.isEmpty()) {
+            return 0;
+        }
+        int deletedCount = 0;
+        final EntityManager mg = getEntityManager();
+        try {
+            mg.getTransaction().begin();
+            for (final PfConceptKey key : keys) {
+                deletedCount += mg.createQuery(DELETE_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_NAME
+                        + key.getName() + AND_C_KEY_VERSION + key.getVersion() + "'", someClass).executeUpdate();
+            }
+            mg.getTransaction().commit();
+        } finally {
+            mg.close();
+        }
+        return deletedCount;
+    }
+
+    @Override
+    public <T extends PfConcept> int deleteByReferenceKey(final Class<T> someClass,
+            final Collection<PfReferenceKey> keys) {
+        if (keys == null || keys.isEmpty()) {
+            return 0;
+        }
+        int deletedCount = 0;
+        final EntityManager mg = getEntityManager();
+        try {
+            mg.getTransaction().begin();
+            for (final PfReferenceKey key : keys) {
+                deletedCount +=
+                        mg.createQuery(
+                                DELETE_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_PARENT_KEY_NAME
+                                        + key.getParentKeyName() + AND_C_KEY_PARENT_KEY_VERSION
+                                        + key.getParentKeyVersion() + AND_C_KEY_LOCAL_NAME + key.getLocalName() + "'",
+                                someClass).executeUpdate();
+            }
+            mg.getTransaction().commit();
+        } finally {
+            mg.close();
+        }
+        return deletedCount;
+    }
+
+    @Override
+    public <T extends PfConcept> void deleteAll(final Class<T> someClass) {
+        final EntityManager mg = getEntityManager();
+        try {
+            mg.getTransaction().begin();
+            mg.createQuery(DELETE_FROM + someClass.getSimpleName() + " c ", someClass).executeUpdate();
+            mg.getTransaction().commit();
+        } finally {
+            mg.close();
+        }
+    }
+
+    @Override
+    public <T extends PfConcept> T get(final Class<T> someClass, final PfConceptKey key) {
+        if (someClass == null) {
+            return null;
+        }
+        final EntityManager mg = getEntityManager();
+        try {
+            final T t = mg.find(someClass, key);
+            if (t != null) {
+                // This clone is created to force the JPA DAO to recurse down through the object
+                try {
+                    final T clonedT = someClass.newInstance();
+                    t.copyTo(clonedT);
+                    return clonedT;
+                } catch (final Exception e) {
+                    LOGGER.warn("Could not clone object of class \"" + someClass.getCanonicalName() + "\"", e);
+                    return null;
+                }
+            } else {
+                return null;
+            }
+        } finally {
+            mg.close();
+        }
+    }
+
+    @Override
+    public <T extends PfConcept> T get(final Class<T> someClass, final PfReferenceKey key) {
+        if (someClass == null) {
+            return null;
+        }
+        final EntityManager mg = getEntityManager();
+        try {
+            final T t = mg.find(someClass, key);
+            if (t != null) {
+                try {
+                    final T clonedT = someClass.newInstance();
+                    t.copyTo(clonedT);
+                    return clonedT;
+                } catch (final Exception e) {
+                    LOGGER.warn("Could not clone object of class \"" + someClass.getCanonicalName() + "\"", e);
+                    return null;
+                }
+            } else {
+                return null;
+            }
+        } finally {
+            mg.close();
+        }
+    }
+
+    @Override
+    public <T extends PfConcept> List<T> getAll(final Class<T> someClass) {
+        if (someClass == null) {
+            return Collections.emptyList();
+        }
+        final EntityManager mg = getEntityManager();
+        try {
+            return mg.createQuery(SELECT_C_FROM + someClass.getSimpleName() + " c", someClass).getResultList();
+        } finally {
+            mg.close();
+        }
+    }
+
+    @Override
+    public <T extends PfConcept> List<T> getAll(final Class<T> someClass, final PfConceptKey parentKey) {
+        if (someClass == null) {
+            return Collections.emptyList();
+        }
+        final EntityManager mg = getEntityManager();
+        try {
+            return mg
+                    .createQuery(
+                            SELECT_C_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_PARENT_KEY_NAME
+                                    + parentKey.getName() + AND_C_KEY_PARENT_KEY_VERSION + parentKey.getVersion() + "'",
+                            someClass)
+                    .getResultList();
+        } finally {
+            mg.close();
+        }
+    }
+
+    @Override
+    public <T extends PfConcept> T getConcept(final Class<T> someClass, final PfConceptKey key) {
+        if (someClass == null || key == null) {
+            return null;
+        }
+        final EntityManager mg = getEntityManager();
+        List<T> ret;
+        try {
+            ret = mg.createQuery(SELECT_C_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_NAME + key.getName()
+                    + AND_C_KEY_VERSION + key.getVersion() + "'", someClass).getResultList();
+        } finally {
+            mg.close();
+        }
+        if (ret == null || ret.isEmpty()) {
+            return null;
+        }
+        if (ret.size() > 1) {
+            throw new IllegalArgumentException("More than one result was returned for search for " + someClass
+                    + " with key " + key.getId() + ": " + ret);
+        }
+        return ret.get(0);
+    }
+
+    @Override
+    public <T extends PfConcept> T getConcept(final Class<T> someClass, final PfReferenceKey key) {
+        if (someClass == null || key == null) {
+            return null;
+        }
+        final EntityManager mg = getEntityManager();
+        List<T> ret;
+        try {
+            ret = mg.createQuery(SELECT_C_FROM + someClass.getSimpleName() + C_WHERE_C_KEY_PARENT_KEY_NAME
+                    + key.getParentKeyName() + AND_C_KEY_PARENT_KEY_VERSION + key.getParentKeyVersion()
+                    + AND_C_KEY_LOCAL_NAME + key.getLocalName() + "'", someClass).getResultList();
+        } finally {
+            mg.close();
+        }
+        if (ret == null || ret.isEmpty()) {
+            return null;
+        }
+        if (ret.size() > 1) {
+            throw new IllegalArgumentException("More than one result was returned for search for " + someClass
+                    + " with key " + key.getId() + ": " + ret);
+        }
+        return ret.get(0);
+    }
+
+    @Override
+    public <T extends PfConcept> T update(final T obj) {
+        final EntityManager mg = getEntityManager();
+        T ret;
+        try {
+            mg.getTransaction().begin();
+            ret = mg.merge(obj);
+            mg.flush();
+            mg.getTransaction().commit();
+        } finally {
+            mg.close();
+        }
+        return ret;
+    }
+
+    @Override
+    public <T extends PfConcept> long size(final Class<T> someClass) {
+        if (someClass == null) {
+            return 0;
+        }
+        final EntityManager mg = getEntityManager();
+        long size = 0;
+        try {
+            size = mg.createQuery("SELECT COUNT(c) FROM " + someClass.getSimpleName() + " c", Long.class)
+                    .getSingleResult();
+        } finally {
+            mg.close();
+        }
+        return size;
+    }
+}
diff --git a/models-dao/src/main/java/org/onap/policy/models/dao/impl/package-info.java b/models-dao/src/main/java/org/onap/policy/models/dao/impl/package-info.java
new file mode 100644
index 0000000..0d27628
--- /dev/null
+++ b/models-dao/src/main/java/org/onap/policy/models/dao/impl/package-info.java
@@ -0,0 +1,25 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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=========================================================
+ */
+
+/**
+ * Contains a default DAO implementation for the PF {@link org.onap.policy.models.base.PfConcept}
+ * classes that uses javax persistence.
+ */
+package org.onap.policy.models.dao.impl;
diff --git a/models-dao/src/main/java/org/onap/policy/models/dao/package-info.java b/models-dao/src/main/java/org/onap/policy/models/dao/package-info.java
new file mode 100644
index 0000000..e8cfbe4
--- /dev/null
+++ b/models-dao/src/main/java/org/onap/policy/models/dao/package-info.java
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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=========================================================
+ */
+
+/**
+ * Defines and implements the Data Access Object (DAO) that allows Apex
+ * {@link org.onap.policy.apex.model.basicmodel.concepts.AxConcept} concepts to be read from and written to databases
+ * over JDBC.
+ */
+
+package org.onap.policy.models.dao;
diff --git a/models-dao/src/test/java/org/onap/policy/models/dao/DaoMiscTest.java b/models-dao/src/test/java/org/onap/policy/models/dao/DaoMiscTest.java
new file mode 100644
index 0000000..4dd70ce
--- /dev/null
+++ b/models-dao/src/test/java/org/onap/policy/models/dao/DaoMiscTest.java
@@ -0,0 +1,89 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.models.dao;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+import java.util.Properties;
+
+import org.junit.Test;
+import org.onap.policy.models.dao.DaoParameters;
+import org.onap.policy.models.dao.PfDaoFactory;
+import org.onap.policy.models.dao.converters.CDataConditioner;
+import org.onap.policy.models.dao.converters.Uuid2String;
+
+public class DaoMiscTest {
+
+    @Test
+    public void testUuid2StringMopUp() {
+        final Uuid2String uuid2String = new Uuid2String();
+        assertEquals("", uuid2String.convertToDatabaseColumn(null));
+    }
+
+    @Test
+    public void testCDataConditionerMopUp() {
+        assertNull(CDataConditioner.clean(null));
+    }
+
+    @Test
+    public void testDaoFactory() {
+        final DaoParameters daoParameters = new DaoParameters();
+
+        daoParameters.setPluginClass("somewhere.over.the.rainbow");
+        try {
+            new PfDaoFactory().createPfDao(daoParameters);
+            fail("test shold throw an exception here");
+        } catch (final Exception e) {
+            assertEquals("Policy Framework DAO class not found for DAO plugin \"somewhere.over.the.rainbow\"",
+                    e.getMessage());
+        }
+
+        daoParameters.setPluginClass("java.lang.String");
+        try {
+            new PfDaoFactory().createPfDao(daoParameters);
+            fail("test shold throw an exception here");
+        } catch (final Exception e) {
+            assertEquals("Specified DAO plugin class \"java.lang.String\" " + "does not implement the PfDao interface",
+                    e.getMessage());
+        }
+    }
+
+    @Test
+    public void testDaoParameters() {
+        final DaoParameters pars = new DaoParameters();
+        pars.setJdbcProperties(new Properties());
+        assertEquals(0, pars.getJdbcProperties().size());
+
+        pars.setJdbcProperty("name", "Dorothy");
+        assertEquals("Dorothy", pars.getJdbcProperty("name"));
+
+        pars.setPersistenceUnit("Kansas");
+        assertEquals("Kansas", pars.getPersistenceUnit());
+
+        pars.setPluginClass("somewhere.over.the.rainbow");
+        assertEquals("somewhere.over.the.rainbow", pars.getPluginClass());
+
+        assertEquals("DAOParameters [pluginClass=somewhere.over.the.rainbow, "
+                + "persistenceUnit=Kansas, jdbcProperties={name=Dorothy}]", pars.toString());
+    }
+}
diff --git a/models-dao/src/test/java/org/onap/policy/models/dao/DummyConceptEntity.java b/models-dao/src/test/java/org/onap/policy/models/dao/DummyConceptEntity.java
new file mode 100644
index 0000000..fa2e71a
--- /dev/null
+++ b/models-dao/src/test/java/org/onap/policy/models/dao/DummyConceptEntity.java
@@ -0,0 +1,139 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.models.dao;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import javax.persistence.Column;
+import javax.persistence.EmbeddedId;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NonNull;
+
+import org.onap.policy.common.utils.validation.Assertions;
+import org.onap.policy.models.base.PfConcept;
+import org.onap.policy.models.base.PfConceptKey;
+import org.onap.policy.models.base.PfKey;
+import org.onap.policy.models.base.PfValidationResult;
+
+@Entity
+@Table(name = "DummyConceptEntity")
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class DummyConceptEntity extends PfConcept {
+    private static final long serialVersionUID = -2962570563281067894L;
+
+    @EmbeddedId()
+    @NonNull
+    private PfConceptKey key;
+
+    @Column
+    @NonNull
+    private UUID uuid;
+
+    @Column
+    @NonNull
+    private String description;
+
+    public DummyConceptEntity() {
+        this.key = new PfConceptKey();
+    }
+
+    public DummyConceptEntity(final Double doubleValue) {
+        this.key = new PfConceptKey();
+    }
+
+    public DummyConceptEntity(final PfConceptKey key, final Double doubleValue) {
+        this.key = key;
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param key the key
+     * @param uuid the uuid
+     * @param description the description
+     */
+    public DummyConceptEntity(PfConceptKey key, UUID uuid, String description) {
+        this.key = key;
+        this.uuid = uuid;
+        this.description = description;
+    }
+
+    @Override
+    public List<PfKey> getKeys() {
+        final List<PfKey> keyList = new ArrayList<>();
+        keyList.add(getKey());
+        return keyList;
+    }
+
+    @Override
+    public PfValidationResult validate(final PfValidationResult result) {
+        return key.validate(result);
+    }
+
+    @Override
+    public void clean() {
+        key.clean();
+    }
+
+    @Override
+    public PfConcept copyTo(final PfConcept target) {
+        Assertions.argumentNotNull(target, "target may not be null");
+
+        final PfConcept copyObject = target;
+        Assertions.instanceOf(copyObject, DummyConceptEntity.class);
+
+        final DummyConceptEntity copy = ((DummyConceptEntity) copyObject);
+        copy.setKey(key);
+        copy.setUuid(uuid);
+        copy.setDescription(description);
+
+        return copyObject;
+    }
+
+    @Override
+    public int compareTo(final PfConcept otherObj) {
+        Assertions.argumentNotNull(otherObj, "comparison object may not be null");
+
+        if (this == otherObj) {
+            return 0;
+        }
+        if (getClass() != otherObj.getClass()) {
+            return this.hashCode() - otherObj.hashCode();
+        }
+
+        final DummyConceptEntity other = (DummyConceptEntity) otherObj;
+
+        if (!key.equals(other.key)) {
+            return key.compareTo(other.key);
+        }
+        if (!uuid.equals(other.uuid)) {
+            return uuid.compareTo(other.uuid);
+        }
+        return description.compareTo(other.description);
+    }
+}
diff --git a/models-dao/src/test/java/org/onap/policy/models/dao/DummyReferenceEntity.java b/models-dao/src/test/java/org/onap/policy/models/dao/DummyReferenceEntity.java
new file mode 100644
index 0000000..044a63d
--- /dev/null
+++ b/models-dao/src/test/java/org/onap/policy/models/dao/DummyReferenceEntity.java
@@ -0,0 +1,121 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.models.dao;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.Column;
+import javax.persistence.EmbeddedId;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NonNull;
+
+import org.onap.policy.common.utils.validation.Assertions;
+import org.onap.policy.models.base.PfConcept;
+import org.onap.policy.models.base.PfKey;
+import org.onap.policy.models.base.PfReferenceKey;
+import org.onap.policy.models.base.PfValidationResult;
+
+@Entity
+@Table(name = "DummyReferenceEntity")
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class DummyReferenceEntity extends PfConcept {
+    private static final long serialVersionUID = -2962570563281067894L;
+
+    @EmbeddedId()
+    @NonNull
+    private PfReferenceKey key;
+
+    @Column
+    private double doubleValue;
+
+    /**
+     * Default constructor.
+     */
+    public DummyReferenceEntity() {
+        this.key = new PfReferenceKey();
+        this.doubleValue = 123.45;
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param key the key
+     * @param doubleValue the double value
+     */
+    public DummyReferenceEntity(final PfReferenceKey key, final double doubleValue) {
+        this.key = key;
+        this.doubleValue = doubleValue;
+    }
+
+    @Override
+    public List<PfKey> getKeys() {
+        final List<PfKey> keyList = new ArrayList<>();
+        keyList.add(getKey());
+        return keyList;
+    }
+
+    @Override
+    public PfValidationResult validate(final PfValidationResult result) {
+        return key.validate(result);
+    }
+
+    @Override
+    public void clean() {
+        key.clean();
+    }
+
+    @Override
+    public PfConcept copyTo(final PfConcept target) {
+        Assertions.argumentNotNull(target, "target may not be null");
+
+        final PfConcept copyObject = target;
+        Assertions.instanceOf(copyObject, DummyReferenceEntity.class);
+
+        final DummyReferenceEntity copy = ((DummyReferenceEntity) copyObject);
+        copy.setKey(key);
+        copy.setDoubleValue(doubleValue);
+
+        return copyObject;
+    }
+
+
+    @Override
+    public int compareTo(final PfConcept otherObj) {
+        Assertions.argumentNotNull(otherObj, "comparison object may not be null");
+
+        if (this == otherObj) {
+            return 0;
+        }
+        if (getClass() != otherObj.getClass()) {
+            return this.hashCode() - otherObj.hashCode();
+        }
+
+        final DummyReferenceEntity other = (DummyReferenceEntity) otherObj;
+
+        return  new Double(doubleValue).compareTo(new Double(other.doubleValue));
+    }
+}
diff --git a/models-dao/src/test/java/org/onap/policy/models/dao/EntityTest.java b/models-dao/src/test/java/org/onap/policy/models/dao/EntityTest.java
new file mode 100644
index 0000000..8278cfe
--- /dev/null
+++ b/models-dao/src/test/java/org/onap/policy/models/dao/EntityTest.java
@@ -0,0 +1,299 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.models.dao;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.UUID;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.policy.models.base.PfConceptKey;
+import org.onap.policy.models.base.PfModelException;
+import org.onap.policy.models.base.PfReferenceKey;
+import org.onap.policy.models.dao.DaoParameters;
+import org.onap.policy.models.dao.PfDao;
+import org.onap.policy.models.dao.PfDaoFactory;
+import org.onap.policy.models.dao.impl.DefaultPfDao;
+
+/**
+ * JUnit test class.
+ */
+public class EntityTest {
+    private Connection connection;
+    private PfDao pfDao;
+
+    @Before
+    public void setup() throws Exception {
+        connection = DriverManager.getConnection("jdbc:h2:mem:test");
+    }
+
+    @After
+    public void teardown() throws Exception {
+        connection.close();
+        new File("derby.log").delete();
+    }
+
+    @Test
+    public void testEntityTestSanity() throws PfModelException {
+        final DaoParameters daoParameters = new DaoParameters();
+
+        pfDao = new PfDaoFactory().createPfDao(daoParameters);
+
+        try {
+            pfDao.init(null);
+            fail("Test should throw an exception here");
+        } catch (final Exception e) {
+            assertEquals("Policy Framework persistence unit parameter not set", e.getMessage());
+        }
+
+        try {
+            pfDao.init(daoParameters);
+            fail("Test should throw an exception here");
+        } catch (final Exception e) {
+            assertEquals("Policy Framework persistence unit parameter not set", e.getMessage());
+        }
+
+        daoParameters.setPluginClass("somewhere.over.the.rainbow");
+        daoParameters.setPersistenceUnit("Dorothy");
+        try {
+            pfDao.init(daoParameters);
+            fail("Test should throw an exception here");
+        } catch (final Exception e) {
+            assertEquals("Creation of Policy Framework persistence unit \"Dorothy\" failed", e.getMessage());
+        }
+        try {
+            pfDao.create(new PfConceptKey());
+            fail("Test should throw an exception here");
+        } catch (final Exception e) {
+            assertEquals("Policy Framework DAO has not been initialized", e.getMessage());
+        }
+        pfDao.close();
+    }
+
+    @Test
+    public void testEntityTestAllOpsJpa() throws PfModelException {
+        final DaoParameters daoParameters = new DaoParameters();
+        daoParameters.setPluginClass(DefaultPfDao.class.getCanonicalName());
+        daoParameters.setPersistenceUnit("DaoTest");
+
+        pfDao = new PfDaoFactory().createPfDao(daoParameters);
+        pfDao.init(daoParameters);
+
+        testAllOps();
+        pfDao.close();
+    }
+
+    @Test
+    public void testEntityTestBadVals() throws PfModelException {
+        final DaoParameters daoParameters = new DaoParameters();
+        daoParameters.setPluginClass(DefaultPfDao.class.getCanonicalName());
+        daoParameters.setPersistenceUnit("DaoTest");
+
+        pfDao = new PfDaoFactory().createPfDao(daoParameters);
+        pfDao.init(daoParameters);
+
+        final PfConceptKey nullKey = null;
+        final PfReferenceKey nullRefKey = null;
+        final List<PfConceptKey> nullKeyList = null;
+        final List<PfConceptKey> emptyKeyList = new ArrayList<>();
+        final List<PfReferenceKey> nullRKeyList = null;
+        final List<PfReferenceKey> emptyRKeyList = new ArrayList<>();
+
+        pfDao.create(nullKey);
+        pfDao.createCollection(nullKeyList);
+        pfDao.createCollection(emptyKeyList);
+
+        pfDao.delete(nullKey);
+        pfDao.deleteCollection(nullKeyList);
+        pfDao.deleteCollection(emptyKeyList);
+        pfDao.delete(PfConceptKey.class, nullKey);
+        pfDao.delete(PfReferenceKey.class, nullRefKey);
+        pfDao.deleteByConceptKey(PfConceptKey.class, nullKeyList);
+        pfDao.deleteByConceptKey(PfConceptKey.class, emptyKeyList);
+        pfDao.deleteByReferenceKey(PfReferenceKey.class, nullRKeyList);
+        pfDao.deleteByReferenceKey(PfReferenceKey.class, emptyRKeyList);
+
+        pfDao.get(null, nullKey);
+        pfDao.get(null, nullRefKey);
+        pfDao.getAll(null);
+        pfDao.getAll(null, nullKey);
+        pfDao.getConcept(null, nullKey);
+        pfDao.getConcept(PfConceptKey.class, nullKey);
+        pfDao.getConcept(null, nullRefKey);
+        pfDao.getConcept(PfReferenceKey.class, nullRefKey);
+        pfDao.size(null);
+
+        pfDao.close();
+    }
+
+    private void testAllOps() {
+        final PfConceptKey aKey0 = new PfConceptKey("A-KEY0", "0.0.1");
+        final PfConceptKey aKey1 = new PfConceptKey("A-KEY1", "0.0.1");
+        final PfConceptKey aKey2 = new PfConceptKey("A-KEY2", "0.0.1");
+        final DummyConceptEntity keyInfo0 = new DummyConceptEntity(aKey0,
+                UUID.fromString("00000000-0000-0000-0000-000000000000"), "key description 0");
+        final DummyConceptEntity keyInfo1 = new DummyConceptEntity(aKey1,
+                UUID.fromString("00000000-0000-0000-0000-000000000001"), "key description 1");
+        final DummyConceptEntity keyInfo2 = new DummyConceptEntity(aKey2,
+                UUID.fromString("00000000-0000-0000-0000-000000000002"), "key description 2");
+
+        pfDao.create(keyInfo0);
+
+        final DummyConceptEntity keyInfoBack0 = pfDao.get(DummyConceptEntity.class, aKey0);
+        assertTrue(keyInfo0.equals(keyInfoBack0));
+
+        final DummyConceptEntity keyInfoBackNull = pfDao.get(DummyConceptEntity.class, PfConceptKey.getNullKey());
+        assertNull(keyInfoBackNull);
+
+        final DummyConceptEntity keyInfoBack1 = pfDao.getConcept(DummyConceptEntity.class, aKey0);
+        assertTrue(keyInfoBack0.equals(keyInfoBack1));
+
+        final DummyConceptEntity keyInfoBack2 =
+                pfDao.getConcept(DummyConceptEntity.class, new PfConceptKey("A-KEY3", "0.0.1"));
+        assertNull(keyInfoBack2);
+
+        final Set<DummyConceptEntity> keyInfoSetIn = new TreeSet<DummyConceptEntity>();
+        keyInfoSetIn.add(keyInfo1);
+        keyInfoSetIn.add(keyInfo2);
+
+        pfDao.createCollection(keyInfoSetIn);
+
+        Set<DummyConceptEntity> keyInfoSetOut = new TreeSet<DummyConceptEntity>(pfDao.getAll(DummyConceptEntity.class));
+
+        keyInfoSetIn.add(keyInfo0);
+        assertTrue(keyInfoSetIn.equals(keyInfoSetOut));
+
+        pfDao.delete(keyInfo1);
+        keyInfoSetIn.remove(keyInfo1);
+        keyInfoSetOut = new TreeSet<DummyConceptEntity>(pfDao.getAll(DummyConceptEntity.class));
+        assertTrue(keyInfoSetIn.equals(keyInfoSetOut));
+
+        pfDao.deleteCollection(keyInfoSetIn);
+        keyInfoSetOut = new TreeSet<DummyConceptEntity>(pfDao.getAll(DummyConceptEntity.class));
+        assertEquals(0, keyInfoSetOut.size());
+
+        keyInfoSetIn.add(keyInfo0);
+        keyInfoSetIn.add(keyInfo1);
+        keyInfoSetIn.add(keyInfo0);
+        pfDao.createCollection(keyInfoSetIn);
+        keyInfoSetOut = new TreeSet<DummyConceptEntity>(pfDao.getAll(DummyConceptEntity.class));
+        assertTrue(keyInfoSetIn.equals(keyInfoSetOut));
+
+        pfDao.delete(DummyConceptEntity.class, aKey0);
+        keyInfoSetOut = new TreeSet<DummyConceptEntity>(pfDao.getAll(DummyConceptEntity.class));
+        assertEquals(2, keyInfoSetOut.size());
+        assertEquals(2, pfDao.size(DummyConceptEntity.class));
+
+        final Set<PfConceptKey> keySetIn = new TreeSet<PfConceptKey>();
+        keySetIn.add(aKey1);
+        keySetIn.add(aKey2);
+
+        final int deletedCount = pfDao.deleteByConceptKey(DummyConceptEntity.class, keySetIn);
+        assertEquals(2, deletedCount);
+
+        keyInfoSetOut = new TreeSet<DummyConceptEntity>(pfDao.getAll(DummyConceptEntity.class));
+        assertEquals(0, keyInfoSetOut.size());
+
+        keyInfoSetIn.add(keyInfo0);
+        keyInfoSetIn.add(keyInfo1);
+        keyInfoSetIn.add(keyInfo0);
+        pfDao.createCollection(keyInfoSetIn);
+        keyInfoSetOut = new TreeSet<DummyConceptEntity>(pfDao.getAll(DummyConceptEntity.class));
+        assertTrue(keyInfoSetIn.equals(keyInfoSetOut));
+
+        pfDao.deleteAll(DummyConceptEntity.class);
+        assertEquals(0, pfDao.size(DummyConceptEntity.class));
+
+        final PfConceptKey owner0Key = new PfConceptKey("Owner0", "0.0.1");
+        final PfConceptKey owner1Key = new PfConceptKey("Owner1", "0.0.1");
+        final PfConceptKey owner2Key = new PfConceptKey("Owner2", "0.0.1");
+        final PfConceptKey owner3Key = new PfConceptKey("Owner3", "0.0.1");
+        final PfConceptKey owner4Key = new PfConceptKey("Owner4", "0.0.1");
+        final PfConceptKey owner5Key = new PfConceptKey("Owner5", "0.0.1");
+
+        pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner0Key, "Entity0"), 100.0));
+        pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner0Key, "Entity1"), 101.0));
+        pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner0Key, "Entity2"), 102.0));
+        pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner0Key, "Entity3"), 103.0));
+        pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner0Key, "Entity4"), 104.0));
+        pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner1Key, "Entity5"), 105.0));
+        pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner1Key, "Entity6"), 106.0));
+        pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner1Key, "Entity7"), 107.0));
+        pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner2Key, "Entity8"), 108.0));
+        pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner2Key, "Entity9"), 109.0));
+        pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner3Key, "EntityA"), 110.0));
+        pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner4Key, "EntityB"), 111.0));
+        pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner5Key, "EntityC"), 112.0));
+        pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner5Key, "EntityD"), 113.0));
+        pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner5Key, "EntityE"), 114.0));
+        pfDao.create(new DummyReferenceEntity(new PfReferenceKey(owner5Key, "EntityF"), 115.0));
+
+        TreeSet<DummyReferenceEntity> testEntitySetOut =
+                new TreeSet<DummyReferenceEntity>(pfDao.getAll(DummyReferenceEntity.class));
+        assertEquals(16, testEntitySetOut.size());
+
+        testEntitySetOut = new TreeSet<DummyReferenceEntity>(pfDao.getAll(DummyReferenceEntity.class, owner0Key));
+        assertEquals(5, testEntitySetOut.size());
+
+        testEntitySetOut = new TreeSet<DummyReferenceEntity>(pfDao.getAll(DummyReferenceEntity.class, owner1Key));
+        assertEquals(3, testEntitySetOut.size());
+
+        testEntitySetOut = new TreeSet<DummyReferenceEntity>(pfDao.getAll(DummyReferenceEntity.class, owner2Key));
+        assertEquals(2, testEntitySetOut.size());
+
+        testEntitySetOut = new TreeSet<DummyReferenceEntity>(pfDao.getAll(DummyReferenceEntity.class, owner3Key));
+        assertEquals(1, testEntitySetOut.size());
+
+        testEntitySetOut = new TreeSet<DummyReferenceEntity>(pfDao.getAll(DummyReferenceEntity.class, owner4Key));
+        assertEquals(1, testEntitySetOut.size());
+
+        testEntitySetOut = new TreeSet<DummyReferenceEntity>(pfDao.getAll(DummyReferenceEntity.class, owner5Key));
+        assertEquals(4, testEntitySetOut.size());
+
+        assertNotNull(pfDao.get(DummyReferenceEntity.class, new PfReferenceKey(owner0Key, "Entity0")));
+        assertNotNull(pfDao.getConcept(DummyReferenceEntity.class, new PfReferenceKey(owner0Key, "Entity0")));
+        assertNull(pfDao.get(DummyReferenceEntity.class, new PfReferenceKey(owner0Key, "Entity1000")));
+        assertNull(pfDao.getConcept(DummyReferenceEntity.class, new PfReferenceKey(owner0Key, "Entity1000")));
+        pfDao.delete(DummyReferenceEntity.class, new PfReferenceKey(owner0Key, "Entity0"));
+
+        final Set<PfReferenceKey> rKeySetIn = new TreeSet<PfReferenceKey>();
+        rKeySetIn.add(new PfReferenceKey(owner4Key, "EntityB"));
+        rKeySetIn.add(new PfReferenceKey(owner5Key, "EntityD"));
+
+        final int deletedRCount = pfDao.deleteByReferenceKey(DummyReferenceEntity.class, rKeySetIn);
+        assertEquals(2, deletedRCount);
+
+        pfDao.update(new DummyReferenceEntity(new PfReferenceKey(owner5Key, "EntityF"), 120.0));
+    }
+}
diff --git a/models-dao/src/test/resources/META-INF/persistence.xml b/models-dao/src/test/resources/META-INF/persistence.xml
new file mode 100644
index 0000000..1f430bc
--- /dev/null
+++ b/models-dao/src/test/resources/META-INF/persistence.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ============LICENSE_START=======================================================
+   Copyright (C) 2019 Nordix Foundation.
+  ================================================================================
+  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.models.dao.converters.CDataConditioner</class>
+        <class>org.onap.policy.models.dao.converters.Uuid2String</class>
+        <class>org.onap.policy.models.base.concepts.PfConcepttKey</class>
+        <class>org.onap.policy.models.dao.DummyConceptEntity</class>
+        <class>org.onap.policy.models.dao.DummyReferenceEntity</class>
+
+        <properties>
+            <property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
+            <property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:testdb" />
+            <property name="javax.persistence.jdbc.user" value="sa" />
+            <property name="javax.persistence.jdbc.password" value="" />
+            <property name="eclipselink.ddl-generation" value="drop-and-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/models-dao/src/test/resources/logback-test.xml b/models-dao/src/test/resources/logback-test.xml
new file mode 100644
index 0000000..f0c510c
--- /dev/null
+++ b/models-dao/src/test/resources/logback-test.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ============LICENSE_START=======================================================
+   Copyright (C) 2019 Nordix Foundation.
+  ================================================================================
+  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>PolicyModels</contextName>
+    <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
+    <property name="LOG_DIR" value="${java.io.tmpdir}/onap_policy_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>
+
+    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
+        <file>${LOG_DIR}/models.log</file>
+        <encoder>
+            <pattern>%d %-5relative [procId=${processId}] [%thread] %-5level
+                %logger{26} - %msg %n %ex{full}</pattern>
+        </encoder>
+    </appender>
+
+    <logger name="org.onap.policy.models.dao" level="INFO" additivity="false">
+        <appender-ref ref="STDOUT" />
+    </logger>
+</configuration>
diff --git a/models-tosca/pom.xml b/models-tosca/pom.xml
new file mode 100644
index 0000000..839cc72
--- /dev/null
+++ b/models-tosca/pom.xml
@@ -0,0 +1,42 @@
+<!--
+  ============LICENSE_START=======================================================
+   Copyright (C) 2019 AT&T Intellectual Property. 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.models</groupId>
+        <artifactId>policy-models</artifactId>
+        <version>2.0.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>policy-models-tosca</artifactId>
+
+    <name>${project.artifactId}</name>
+    <description>The platform models that are shared across different policy components</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.onap.policy.models</groupId>
+            <artifactId>policy-models-base</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/platform/src/main/java/org/onap/policy/model/tosca/ToscaConstraint.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaConstraint.java
similarity index 97%
rename from platform/src/main/java/org/onap/policy/model/tosca/ToscaConstraint.java
rename to models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaConstraint.java
index 21ae4c5..47a4d35 100644
--- a/platform/src/main/java/org/onap/policy/model/tosca/ToscaConstraint.java
+++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaConstraint.java
@@ -20,7 +20,7 @@
  * ============LICENSE_END=========================================================
  */
 
-package org.onap.policy.model.tosca;
+package org.onap.policy.models.tosca;
 
 import com.google.gson.annotations.SerializedName;
 import lombok.Getter;
@@ -28,7 +28,7 @@
 import lombok.ToString;
 
 /**
- * Class to represent the Constraint of property in TOSCA definition
+ * Class to represent the Constraint of property in TOSCA definition.
  *
  * @author Chenfei Gao (cgao@research.att.com)
  *
diff --git a/platform/src/main/java/org/onap/policy/model/tosca/ToscaDataType.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaDataType.java
similarity index 94%
rename from platform/src/main/java/org/onap/policy/model/tosca/ToscaDataType.java
rename to models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaDataType.java
index 607c53c..0366ee4 100644
--- a/platform/src/main/java/org/onap/policy/model/tosca/ToscaDataType.java
+++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaDataType.java
@@ -20,24 +20,24 @@
  * ============LICENSE_END=========================================================
  */
 
-package org.onap.policy.model.tosca;
+package org.onap.policy.models.tosca;
 
 import com.google.gson.annotations.SerializedName;
 import java.util.List;
 import java.util.Map;
+
 import lombok.Getter;
 import lombok.Setter;
 import lombok.ToString;
 
 /**
- * Class to represent custom data type in TOSCA definition
+ * Class to represent custom data type in TOSCA definition.
  *
  * @author Chenfei Gao (cgao@research.att.com)
  *
  */
 @ToString
 public class ToscaDataType {
-
     @Getter
     @Setter
     @SerializedName("derived_from")
diff --git a/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaEntityType.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaEntityType.java
new file mode 100644
index 0000000..52a82cc
--- /dev/null
+++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaEntityType.java
@@ -0,0 +1,168 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.models.tosca;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.TreeMap;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.EmbeddedId;
+import javax.persistence.Entity;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NonNull;
+
+import org.onap.policy.common.utils.validation.Assertions;
+import org.onap.policy.models.base.PfConcept;
+import org.onap.policy.models.base.PfConceptKey;
+import org.onap.policy.models.base.PfKey;
+import org.onap.policy.models.base.PfValidationResult;
+
+/**
+ * Class to represent the EntrySchema of list/map property in TOSCA definition.
+ */
+@Entity
+@Table(name = "ToscaEntityType")
+@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class ToscaEntityType extends PfConcept {
+    private static final long serialVersionUID = -1330661834220739393L;
+
+    @EmbeddedId
+    @NonNull
+    private PfConceptKey key = PfConceptKey.getNullKey();
+
+    @SerializedName("derived_from")
+    @Column(name = "derivedFrom")
+    private PfConceptKey derivedFrom;
+
+    @OneToMany(cascade = CascadeType.ALL)
+    private Map<String, String> metadata;
+
+    @Column(name = "description")
+    private String description;
+
+    /**
+     * The Default Constructor creates a {@link ToscaEntityType} object with a null key.
+     */
+    public ToscaEntityType() {
+        this(new PfConceptKey());
+    }
+
+    /**
+     * The Key Constructor creates a {@link ToscaEntityType} object with the given concept key.
+     *
+     * @param key the key
+     */
+    public ToscaEntityType(@NonNull final PfConceptKey key) {
+        this.key = key;
+    }
+
+    /**
+     * Copy constructor.
+     *
+     * @param copyConcept the concept to copy from
+     */
+    public ToscaEntityType(final ToscaEntityType copyConcept) {
+        super(copyConcept);
+    }
+
+    @Override
+    public List<PfKey> getKeys() {
+        final List<PfKey> keyList = new ArrayList<>();
+        keyList.add(getKey());
+        return keyList;
+    }
+
+    @Override
+    public void clean() {
+        description = description.trim();
+
+        for (Entry<String, String> metadataEntry : metadata.entrySet()) {
+            metadataEntry.setValue(metadataEntry.getValue().trim());
+        }
+    }
+
+    @Override
+    public PfValidationResult validate(PfValidationResult result) {
+        return null;
+    }
+
+    @Override
+    public int compareTo(final PfConcept otherConcept) {
+        if (otherConcept == null) {
+            return -1;
+        }
+        if (this == otherConcept) {
+            return 0;
+        }
+        if (getClass() != otherConcept.getClass()) {
+            return this.hashCode() - otherConcept.hashCode();
+        }
+
+        final ToscaEntityType other = (ToscaEntityType) otherConcept;
+        if (!key.equals(other.key)) {
+            return key.compareTo(other.key);
+        }
+
+        if (!derivedFrom.equals(other.derivedFrom)) {
+            return derivedFrom.compareTo(other.derivedFrom);
+        }
+
+        if (!metadata.equals(other.metadata)) {
+            return (metadata.hashCode() - other.metadata.hashCode());
+        }
+
+        return description.compareTo(other.description);
+    }
+
+    @Override
+    public PfConcept copyTo(@NonNull PfConcept target) {
+        final Object copyObject = target;
+        Assertions.instanceOf(copyObject, PfConcept.class);
+
+        final ToscaEntityType copy = ((ToscaEntityType) copyObject);
+        copy.key = new PfConceptKey(key);
+        copy.derivedFrom = new PfConceptKey(derivedFrom);
+
+        final Map<String, String> newMatadata = new TreeMap<>();
+        for (final Entry<String, String> metadataEntry : metadata.entrySet()) {
+            newMatadata.put(metadataEntry.getKey(), metadataEntry.getValue());
+        }
+        copy.metadata = newMatadata;
+
+        copy.description = description;
+
+        return copy;
+    }
+}
diff --git a/platform/src/main/java/org/onap/policy/model/tosca/ToscaEntrySchema.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaEntrySchema.java
similarity index 96%
rename from platform/src/main/java/org/onap/policy/model/tosca/ToscaEntrySchema.java
rename to models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaEntrySchema.java
index b036dc6..b3079af 100644
--- a/platform/src/main/java/org/onap/policy/model/tosca/ToscaEntrySchema.java
+++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaEntrySchema.java
@@ -20,16 +20,17 @@
  * ============LICENSE_END=========================================================
  */
 
-package org.onap.policy.model.tosca;
+package org.onap.policy.models.tosca;
 
 import com.google.gson.annotations.SerializedName;
 import java.util.List;
+
 import lombok.Getter;
 import lombok.Setter;
 import lombok.ToString;
 
 /**
- * Class to represent the EntrySchema of list/map property in TOSCA definition
+ * Class to represent the EntrySchema of list/map property in TOSCA definition.
  *
  * @author Chenfei Gao (cgao@research.att.com)
  *
diff --git a/platform/src/main/java/org/onap/policy/model/tosca/ToscaEventFilter.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaEventFilter.java
similarity index 93%
rename from platform/src/main/java/org/onap/policy/model/tosca/ToscaEventFilter.java
rename to models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaEventFilter.java
index 74277d3..34d7912 100644
--- a/platform/src/main/java/org/onap/policy/model/tosca/ToscaEventFilter.java
+++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaEventFilter.java
@@ -20,7 +20,7 @@
  * ============LICENSE_END=========================================================
  */
 
-package org.onap.policy.model.tosca;
+package org.onap.policy.models.tosca;
 
 import com.google.gson.annotations.SerializedName;
 import lombok.Getter;
@@ -28,7 +28,7 @@
 import lombok.ToString;
 
 /**
- * Class to represent the EventFilter in TOSCA definition
+ * Class to represent the EventFilter in TOSCA definition.
  *
  * @author Chenfei Gao (cgao@research.att.com)
  *
diff --git a/platform/src/main/java/org/onap/policy/model/tosca/ToscaPolicy.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaPolicy.java
similarity index 94%
rename from platform/src/main/java/org/onap/policy/model/tosca/ToscaPolicy.java
rename to models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaPolicy.java
index 8f72dcb..4f9210c 100644
--- a/platform/src/main/java/org/onap/policy/model/tosca/ToscaPolicy.java
+++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaPolicy.java
@@ -20,7 +20,7 @@
  * ============LICENSE_END=========================================================
  */
 
-package org.onap.policy.model.tosca;
+package org.onap.policy.models.tosca;
 
 import com.google.gson.annotations.SerializedName;
 import java.util.List;
@@ -30,7 +30,7 @@
 import lombok.ToString;
 
 /**
- * Class to represent the policy in TOSCA definition
+ * Class to represent the policy in TOSCA definition.
  *
  * @author Chenfei Gao (cgao@research.att.com)
  *
diff --git a/platform/src/main/java/org/onap/policy/model/tosca/ToscaPolicyList.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaPolicyList.java
similarity index 93%
rename from platform/src/main/java/org/onap/policy/model/tosca/ToscaPolicyList.java
rename to models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaPolicyList.java
index ecc1251..ad8f1a4 100644
--- a/platform/src/main/java/org/onap/policy/model/tosca/ToscaPolicyList.java
+++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaPolicyList.java
@@ -20,7 +20,7 @@
  * ============LICENSE_END=========================================================
  */
 
-package org.onap.policy.model.tosca;
+package org.onap.policy.models.tosca;
 
 import com.google.gson.annotations.SerializedName;
 import java.util.List;
@@ -30,7 +30,7 @@
 import lombok.ToString;
 
 /**
- * Class to represent the policy list in TOSCA definition
+ * Class to represent the policy list in TOSCA definition.
  *
  * @author Chenfei Gao (cgao@research.att.com)
  *
diff --git a/platform/src/main/java/org/onap/policy/model/tosca/ToscaPolicyType.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaPolicyType.java
similarity index 94%
rename from platform/src/main/java/org/onap/policy/model/tosca/ToscaPolicyType.java
rename to models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaPolicyType.java
index 8bb5200..241e178 100644
--- a/platform/src/main/java/org/onap/policy/model/tosca/ToscaPolicyType.java
+++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaPolicyType.java
@@ -20,7 +20,7 @@
  * ============LICENSE_END=========================================================
  */
 
-package org.onap.policy.model.tosca;
+package org.onap.policy.models.tosca;
 
 import com.google.gson.annotations.SerializedName;
 import java.util.List;
@@ -30,7 +30,7 @@
 import lombok.ToString;
 
 /**
- * Class to represent the policy type in TOSCA definition
+ * Class to represent the policy type in TOSCA definition.
  *
  * @author Chenfei Gao (cgao@research.att.com)
  *
diff --git a/platform/src/main/java/org/onap/policy/model/tosca/ToscaPolicyTypeList.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaPolicyTypeList.java
similarity index 93%
rename from platform/src/main/java/org/onap/policy/model/tosca/ToscaPolicyTypeList.java
rename to models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaPolicyTypeList.java
index d5ca357..4a6a42d 100644
--- a/platform/src/main/java/org/onap/policy/model/tosca/ToscaPolicyTypeList.java
+++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaPolicyTypeList.java
@@ -20,7 +20,7 @@
  * ============LICENSE_END=========================================================
  */
 
-package org.onap.policy.model.tosca;
+package org.onap.policy.models.tosca;
 
 import com.google.gson.annotations.SerializedName;
 import java.util.List;
@@ -30,7 +30,7 @@
 import lombok.ToString;
 
 /**
- * Class to represent the policy type list in TOSCA definition
+ * Class to represent the policy type list in TOSCA definition.
  *
  * @author Chenfei Gao (cgao@research.att.com)
  *
diff --git a/platform/src/main/java/org/onap/policy/model/tosca/ToscaProperty.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaProperty.java
similarity index 88%
rename from platform/src/main/java/org/onap/policy/model/tosca/ToscaProperty.java
rename to models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaProperty.java
index 6196637..4ee5c45 100644
--- a/platform/src/main/java/org/onap/policy/model/tosca/ToscaProperty.java
+++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaProperty.java
@@ -20,16 +20,21 @@
  * ============LICENSE_END=========================================================
  */
 
-package org.onap.policy.model.tosca;
+package org.onap.policy.models.tosca;
 
 import com.google.gson.annotations.SerializedName;
 import java.util.List;
+
+import javax.persistence.Column;
+
 import lombok.Getter;
 import lombok.Setter;
 import lombok.ToString;
 
+import org.onap.policy.models.base.PfConceptKey;
+
 /**
- * Class to represent the property in TOSCA definition
+ * Class to represent the property in TOSCA definition.
  *
  * @author Chenfei Gao (cgao@research.att.com)
  *
@@ -40,7 +45,8 @@
     @Getter
     @Setter
     @SerializedName("type")
-    private String type;
+    @Column(name = "derivedFrom")
+    private PfConceptKey type;
 
     @Getter
     @Setter
diff --git a/platform/src/main/java/org/onap/policy/model/tosca/ToscaTimeInterval.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaTimeInterval.java
similarity index 93%
rename from platform/src/main/java/org/onap/policy/model/tosca/ToscaTimeInterval.java
rename to models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaTimeInterval.java
index d63b4e0..86334ab 100644
--- a/platform/src/main/java/org/onap/policy/model/tosca/ToscaTimeInterval.java
+++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaTimeInterval.java
@@ -20,7 +20,7 @@
  * ============LICENSE_END=========================================================
  */
 
-package org.onap.policy.model.tosca;
+package org.onap.policy.models.tosca;
 
 import com.google.gson.annotations.SerializedName;
 import lombok.Getter;
@@ -28,14 +28,13 @@
 import lombok.ToString;
 
 /**
- * Class to represent the TimeInterval in TOSCA definition
+ * Class to represent the TimeInterval in TOSCA definition.
  *
  * @author Chenfei Gao (cgao@research.att.com)
  *
  */
 @ToString
 public class ToscaTimeInterval {
-
     @Getter
     @Setter
     @SerializedName("start_time")
@@ -45,4 +44,5 @@
     @Setter
     @SerializedName("end_time")
     private String endTime;
+
 }
\ No newline at end of file
diff --git a/platform/src/main/java/org/onap/policy/model/tosca/ToscaTrigger.java b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaTrigger.java
similarity index 97%
rename from platform/src/main/java/org/onap/policy/model/tosca/ToscaTrigger.java
rename to models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaTrigger.java
index f5ca07c..2464c2e 100644
--- a/platform/src/main/java/org/onap/policy/model/tosca/ToscaTrigger.java
+++ b/models-tosca/src/main/java/org/onap/policy/models/tosca/ToscaTrigger.java
@@ -20,7 +20,7 @@
  * ============LICENSE_END=========================================================
  */
 
-package org.onap.policy.model.tosca;
+package org.onap.policy.models.tosca;
 
 import com.google.gson.annotations.SerializedName;
 import lombok.Getter;
@@ -28,7 +28,7 @@
 import lombok.ToString;
 
 /**
- * Class to represent the trigger of policy type in TOSCA definition
+ * Class to represent the trigger of policy type in TOSCA definition.
  *
  * @author Chenfei Gao (cgao@research.att.com)
  *
diff --git a/platform/src/test/java/org/onap/policy/tosca/TestPojos.java b/models-tosca/src/test/java/org/onap/policy/models/tosca/TestPojos.java
similarity index 94%
rename from platform/src/test/java/org/onap/policy/tosca/TestPojos.java
rename to models-tosca/src/test/java/org/onap/policy/models/tosca/TestPojos.java
index e86c759..28cd4cc 100644
--- a/platform/src/test/java/org/onap/policy/tosca/TestPojos.java
+++ b/models-tosca/src/test/java/org/onap/policy/models/tosca/TestPojos.java
@@ -20,7 +20,7 @@
  * ============LICENSE_END=========================================================
  */
 
-package org.onap.policy.tosca;
+package org.onap.policy.models.tosca;
 
 import com.openpojo.reflection.filters.FilterPackageInfo;
 import com.openpojo.validation.Validator;
@@ -34,14 +34,14 @@
 import org.onap.policy.common.utils.validation.ToStringTester;
 
 /**
- * Class to perform unit tests of all pojos
+ * Class to perform unit tests of all pojos.
  *
  * @author Chenfei Gao (cgao@research.att.com)
  *
  */
 public class TestPojos {
 
-    private static final String POJO_PACKAGE = "org.onap.policy.model.tosca";
+    private static final String POJO_PACKAGE = "org.onap.policy.models.tosca";
 
     @Test
     public void testPojos() {
diff --git a/platform/pom.xml b/platform/pom.xml
deleted file mode 100644
index 8e04348..0000000
--- a/platform/pom.xml
+++ /dev/null
@@ -1,68 +0,0 @@
-<!--
-  ============LICENSE_START=======================================================
-   Copyright (C) 2019 AT&T Intellectual Property. 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.models</groupId>
-      <artifactId>policy-models</artifactId>
-      <version>2.0.0-SNAPSHOT</version>
-    </parent>
-
-    <artifactId>platform</artifactId>
-
-    <name>${project.artifactId}</name>
-    <description>The platform models that are shared across different policy components</description>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.projectlombok</groupId>
-            <artifactId>lombok</artifactId>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>com.google.code.gson</groupId>
-            <artifactId>gson</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.onap.policy.common</groupId>
-            <artifactId>utils</artifactId>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <resources>
-            <!-- Output the version of the pap service -->
-            <resource>
-                <directory>src/main/resources</directory>
-                <filtering>true</filtering>
-                <includes>
-                    <include>**/version.txt</include>
-                </includes>
-            </resource>
-            <resource>
-                <directory>src/main/resources</directory>
-                <filtering>false</filtering>
-                <excludes>
-                    <exclude>**/version.txt</exclude>
-                </excludes>
-            </resource>
-        </resources>
-    </build>
-</project>
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index f337726..0ee588c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -20,7 +20,8 @@
   ============LICENSE_END=========================================================
 -->
 
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+<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>
@@ -38,29 +39,22 @@
     <description>This repo holds model code agnostic to PDP engines</description>
 
     <properties>
+        <derby.version>10.13.1.1</derby.version>
+        <policy.common.version>1.4.0-SNAPSHOT</policy.common.version>
+
         <!-- sonar/jacoco overrides -->
         <!-- Overriding oparent default sonar/jacoco settings Combine all our reports into one file shared across sub-modules -->
         <sonar.jacoco.reportPath>${project.basedir}/../target/code-coverage/jacoco-ut.exec</sonar.jacoco.reportPath>
         <sonar.jacoco.itReportPath>${project.basedir}/../target/code-coverage/jacoco-it.exec</sonar.jacoco.itReportPath>
         <sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
-
-        <policy.common.version>1.4.0-SNAPSHOT</policy.common.version>
     </properties>
 
     <modules>
-        <module>platform</module>
         <module>models-base</module>
         <module>models-dao</module>
+        <module>models-tosca</module>
     </modules>
 
-    <dependencies>
-        <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-
     <distributionManagement>
         <site>
             <id>ecomp-site</id>
@@ -68,6 +62,41 @@
         </site>
     </distributionManagement>
 
+    <dependencies>
+        <dependency>
+            <groupId>org.onap.policy.common</groupId>
+            <artifactId>utils</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.eclipse.persistence</groupId>
+            <artifactId>eclipselink</artifactId>
+        </dependency>
+
+    </dependencies>
+
     <dependencyManagement>
         <dependencies>
             <dependency>