diff --git a/repository/src/main/java/org/apache/atlas/query/QueryParser.java b/repository/src/main/java/org/apache/atlas/query/QueryParser.java
index be2d9b1..1e5e5ff 100644
--- a/repository/src/main/java/org/apache/atlas/query/QueryParser.java
+++ b/repository/src/main/java/org/apache/atlas/query/QueryParser.java
@@ -19,11 +19,20 @@
 
 import org.apache.atlas.query.Expressions.Expression;
 
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
 
 
 public class QueryParser {
+    private static final Set<String> RESERVED_KEYWORDS =
+            new HashSet<>(Arrays.asList("[", "]", "(", ")", "=", "<", ">", "!=", "<=", ">=", ",", "and", "or", "+", "-",
+                                        "*", "/", ".", "select", "from", "where", "groupby", "loop", "isa", "is", "has",
+                                        "as", "times", "withPath", "limit", "offset", "orderby", "count", "max", "min",
+                                        "sum", "by", "order", "like"));
+
     public static boolean isKeyword(String word) {
-        return false; // TODO:
+        return RESERVED_KEYWORDS.contains(word);
     }
 
     public static Expression apply(String queryStr, QueryParams params) {
diff --git a/repository/src/test/java/org/apache/atlas/repository/impexp/AtlasImportRequestTest.java b/repository/src/test/java/org/apache/atlas/repository/impexp/AtlasImportRequestTest.java
new file mode 100644
index 0000000..b70b181
--- /dev/null
+++ b/repository/src/test/java/org/apache/atlas/repository/impexp/AtlasImportRequestTest.java
@@ -0,0 +1,145 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.repository.impexp;
+
+import org.apache.atlas.model.impexp.AtlasImportRequest;
+import org.apache.atlas.type.AtlasType;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.*;
+
+public class AtlasImportRequestTest {
+    @Test
+    public void serializeAtlasImportRequstFromJsonWithEmptyOptions() {
+        String jsonData = "{ \"options\": {} }";
+
+        AtlasImportRequest request = AtlasType.fromJson(jsonData, AtlasImportRequest.class);
+
+        assertNotNull(request);
+        assertNotNull(request.getOptions());
+        assertNull(request.getOptions().get(AtlasImportRequest.TRANSFORMS_KEY));
+
+        ImportTransforms tr = ImportTransforms.fromJson(request.getOptions().get(AtlasImportRequest.TRANSFORMS_KEY));
+
+        assertNull(tr);
+    }
+
+    @Test
+    public void serializeOptions_VerifyAccessors() {
+        String guid = "\"abcd\"";
+        String pos = "\"1\"";
+        String trueVal = "\"true\"";
+
+        String jsonData = "{ \"options\": " +
+                "               {" +
+                "\"startGuid\":" + guid + "," +
+                "\"startPosition\":" + pos + "," +
+                "\"updateTypeDefinition\":" + trueVal +
+                "}" +
+                "}";
+
+        AtlasImportRequest request = AtlasType.fromJson(jsonData, AtlasImportRequest.class);
+
+        assertNotNull(request);
+        assertNotNull(request.getStartGuid());
+        assertNotNull(request.getStartPosition());
+        assertNotNull(request.getUpdateTypeDefs());
+
+        assertEquals(request.getStartGuid(), guid.replace("\"", ""));
+        assertEquals(request.getStartPosition(), pos.replace("\"", ""));
+        assertEquals(request.getUpdateTypeDefs(), trueVal.replace("\"", ""));
+    }
+
+    @Test
+    public void optionsDefaultsTest() {
+        String jsonData = "{ \"options\": " +
+                "               {" +
+                    "}" +
+                "}";
+
+        AtlasImportRequest request = AtlasType.fromJson(jsonData, AtlasImportRequest.class);
+
+        assertNotNull(request);
+        assertNull(request.getStartGuid());
+        assertNull(request.getStartPosition());
+        assertNull(request.getUpdateTypeDefs());
+    }
+
+    @Test
+    public void serializeAtlasImportRequstFromJsonWithEmptyTransforms() {
+        String jsonData = "{ \"options\": { \"transforms\": \"{ }\" } }";
+
+        AtlasImportRequest request = AtlasType.fromJson(jsonData, AtlasImportRequest.class);
+
+        assertNotNull(request);
+        assertNotNull(request.getOptions());
+        assertNotNull(request.getOptions().get(AtlasImportRequest.TRANSFORMS_KEY));
+
+        ImportTransforms tr = ImportTransforms.fromJson(request.getOptions().get(AtlasImportRequest.TRANSFORMS_KEY));
+
+        assertNotNull(tr);
+        assertNotNull(tr.getTransforms());
+        assertEquals(tr.getTransforms().size(), 0);
+    }
+
+    @Test
+    public void serializeAtlasImportRequstFromJsonWith1Transform() {
+        String jsonData = "{ \"options\": { \"transforms\": \"{ \\\"hive_db\\\": { \\\"qualifiedName\\\": [ \\\"replace:@cl1:@cl2\\\" ] } }\" } }";
+
+        AtlasImportRequest request = AtlasType.fromJson(jsonData, AtlasImportRequest.class);
+
+        assertNotNull(request);
+        assertNotNull(request.getOptions());
+        assertNotNull(request.getOptions().get(AtlasImportRequest.TRANSFORMS_KEY));
+
+        ImportTransforms tr = ImportTransforms.fromJson(request.getOptions().get(AtlasImportRequest.TRANSFORMS_KEY));
+
+        assertNotNull(tr);
+        assertNotNull(tr.getTransforms());
+        assertEquals(tr.getTransforms().size(), 1);
+        assertTrue(tr.getTransforms().containsKey("hive_db"));
+        assertEquals(tr.getTransforms("hive_db").entrySet().size(), 1);
+        assertTrue(tr.getTransforms("hive_db").containsKey("qualifiedName"));
+        assertEquals(tr.getTransforms("hive_db").get("qualifiedName").size(), 1);
+    }
+
+    @Test
+    public void serializeAtlasImportRequstFromJson() {
+        String jsonData = "{ \"options\": { \"transforms\": \"{ \\\"hive_db\\\": { \\\"qualifiedName\\\": [ \\\"replace:@cl1:@cl2\\\" ] }, \\\"hive_table\\\": { \\\"qualifiedName\\\": [ \\\"lowercase\\\", \\\"replace:@cl1:@cl2\\\" ] } }\" } } }";
+
+        AtlasImportRequest request = AtlasType.fromJson(jsonData, AtlasImportRequest.class);
+
+        assertNotNull(request);
+        assertNotNull(request.getOptions());
+        assertNotNull(request.getOptions().get(AtlasImportRequest.TRANSFORMS_KEY));
+
+        ImportTransforms tr = ImportTransforms.fromJson(request.getOptions().get(AtlasImportRequest.TRANSFORMS_KEY));
+
+        assertNotNull(tr);
+        assertNotNull(tr.getTransforms());
+        assertEquals(tr.getTransforms().size(), 2);
+        assertTrue(tr.getTransforms().containsKey("hive_db"));
+        assertEquals(tr.getTransforms("hive_db").entrySet().size(), 1);
+        assertTrue(tr.getTransforms("hive_db").containsKey("qualifiedName"));
+        assertEquals(tr.getTransforms("hive_db").get("qualifiedName").size(), 1);
+        assertTrue(tr.getTransforms().containsKey("hive_table"));
+        assertEquals(tr.getTransforms("hive_table").entrySet().size(), 1);
+        assertTrue(tr.getTransforms("hive_table").containsKey("qualifiedName"));
+        assertEquals(tr.getTransforms("hive_table").get("qualifiedName").size(), 2);
+    }
+}
diff --git a/repository/src/test/java/org/apache/atlas/repository/impexp/ExportServiceTest.java b/repository/src/test/java/org/apache/atlas/repository/impexp/ExportServiceTest.java
new file mode 100644
index 0000000..2a8bdfa
--- /dev/null
+++ b/repository/src/test/java/org/apache/atlas/repository/impexp/ExportServiceTest.java
@@ -0,0 +1,358 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.repository.impexp;
+
+
+import org.apache.atlas.RequestContextV1;
+import org.apache.atlas.TestModules;
+import org.apache.atlas.TestUtilsV2;
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.impexp.AtlasExportRequest;
+import org.apache.atlas.model.impexp.AtlasExportResult;
+import org.apache.atlas.model.instance.AtlasEntity;
+import org.apache.atlas.model.instance.AtlasObjectId;
+import org.apache.atlas.model.typedef.AtlasTypesDef;
+import org.apache.atlas.repository.graph.AtlasGraphProvider;
+import org.apache.atlas.repository.store.bootstrap.AtlasTypeDefStoreInitializer;
+import org.apache.atlas.repository.store.graph.v1.AtlasEntityChangeNotifier;
+import org.apache.atlas.repository.store.graph.v1.AtlasEntityStoreV1;
+import org.apache.atlas.repository.store.graph.v1.AtlasEntityStream;
+import org.apache.atlas.repository.store.graph.v1.DeleteHandlerV1;
+import org.apache.atlas.repository.store.graph.v1.EntityGraphMapper;
+import org.apache.atlas.repository.store.graph.v1.SoftDeleteHandlerV1;
+import org.apache.atlas.store.AtlasTypeDefStore;
+import org.apache.atlas.type.AtlasTypeRegistry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+
+import javax.inject.Inject;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.mockito.Mockito.mock;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+@Guice(modules = TestModules.TestOnlyModule.class)
+public class ExportServiceTest {
+    private static final Logger LOG = LoggerFactory.getLogger(ExportServiceTest.class);
+
+    @Inject
+    AtlasTypeRegistry typeRegistry;
+
+    @Inject
+    private AtlasTypeDefStore typeDefStore;
+
+    @Inject
+    private EntityGraphMapper graphMapper;
+    @Inject
+    ExportService exportService;
+    private DeleteHandlerV1 deleteHandler = mock(SoftDeleteHandlerV1.class);;
+    private AtlasEntityChangeNotifier mockChangeNotifier = mock(AtlasEntityChangeNotifier.class);
+    private AtlasEntityStoreV1 entityStore;
+
+    @BeforeTest
+    public void setupTest() {
+        RequestContextV1.clear();
+        RequestContextV1.get().setUser(TestUtilsV2.TEST_USER);
+    }
+
+    @BeforeClass
+    public void setupSampleData() throws AtlasBaseException {
+        entityStore = new AtlasEntityStoreV1(deleteHandler, typeRegistry, mockChangeNotifier, graphMapper);;
+
+        AtlasTypesDef sampleTypes = TestUtilsV2.defineDeptEmployeeTypes();
+        AtlasTypesDef typesToCreate = AtlasTypeDefStoreInitializer.getTypesToCreate(sampleTypes, typeRegistry);
+
+        if (!typesToCreate.isEmpty()) {
+            typeDefStore.createTypesDef(typesToCreate);
+        }
+
+        AtlasEntity.AtlasEntitiesWithExtInfo  hrDept = TestUtilsV2.createDeptEg2();
+
+        AtlasEntityStream entityStream = new AtlasEntityStream(hrDept);
+        entityStore.createOrUpdate(entityStream, false);
+        LOG.debug("==> setupSampleData: ", AtlasEntity.dumpObjects(hrDept.getEntities(), null).toString());
+    }
+
+    @AfterClass
+    public void clear() {
+        AtlasGraphProvider.cleanup();
+    }
+
+    private AtlasExportRequest getRequestForFullFetch() {
+        AtlasExportRequest request = new AtlasExportRequest();
+
+        List<AtlasObjectId> itemsToExport = new ArrayList<>();
+        itemsToExport.add(new AtlasObjectId("hive_db", "qualifiedName", "default@cl1"));
+        request.setItemsToExport(itemsToExport);
+
+        return request;
+    }
+
+    private AtlasExportRequest getRequestForDept(boolean addFetchType, String fetchTypeValue, boolean addMatchType, String matchTypeValue) {
+        AtlasExportRequest request = new AtlasExportRequest();
+
+        List<AtlasObjectId> itemsToExport = new ArrayList<>();
+        itemsToExport.add(new AtlasObjectId("Department", "name", "hr"));
+        request.setItemsToExport(itemsToExport);
+
+        setOptionsMap(request, addFetchType, fetchTypeValue, addMatchType, matchTypeValue);
+        return request;
+    }
+
+    private AtlasExportRequest getRequestForEmployee() {
+        AtlasExportRequest request = new AtlasExportRequest();
+
+        List<AtlasObjectId> itemsToExport = new ArrayList<>();
+        itemsToExport.add(new AtlasObjectId("Employee", "name", "Max"));
+        request.setItemsToExport(itemsToExport);
+
+        setOptionsMap(request, true, "CONNECTED", false, "");
+        return request;
+    }
+
+    private void setOptionsMap(AtlasExportRequest request,
+                               boolean addFetchType, String fetchTypeValue, boolean addMatchType, String matchTypeValue) {
+        Map<String, Object> optionsMap = null;
+        if(addFetchType) {
+            if(optionsMap == null) {
+                optionsMap = new HashMap<>();
+            }
+
+            optionsMap.put("fetchType", fetchTypeValue);
+            request.setOptions(optionsMap);
+        }
+
+        if(addMatchType) {
+            if(optionsMap == null) {
+                optionsMap = new HashMap<>();
+            }
+
+            optionsMap.put("matchType", matchTypeValue);
+        }
+
+        if(optionsMap != null) {
+            request.setOptions(optionsMap);
+        }
+    }
+
+    private ZipSource runExportWithParameters(AtlasExportRequest request) throws AtlasBaseException, IOException {
+        final String requestingIP = "1.0.0.0";
+        final String hostName = "localhost";
+        final String userName = "admin";
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ZipSink zipSink = new ZipSink(baos);
+        AtlasExportResult result = exportService.run(zipSink, request, userName, hostName, requestingIP);
+
+        zipSink.close();
+
+        ByteArrayInputStream bis = new ByteArrayInputStream(baos.toByteArray());
+        ZipSource zipSource = new ZipSource(bis);
+        return zipSource;
+    }
+
+    @Test
+    public void exportType_Succeeds() throws AtlasBaseException, FileNotFoundException {
+        String requestingIP = "1.0.0.0";
+        String hostName = "root";
+
+        AtlasExportRequest request = getRequestForFullFetch();
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ZipSink zipSink = new ZipSink(baos);
+        AtlasExportResult result = exportService.run(zipSink, request, "admin", hostName, requestingIP);
+
+        assertNotNull(exportService);
+        assertEquals(result.getHostName(), hostName);
+        assertEquals(result.getClientIpAddress(), requestingIP);
+        assertEquals(request, result.getRequest());
+    }
+
+    @Test
+    public void requestingEntityNotFound_NoData() throws AtlasBaseException, IOException {
+        String requestingIP = "1.0.0.0";
+        String hostName = "root";
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ZipSink zipSink = new ZipSink(baos);
+        AtlasExportResult result = exportService.run(
+                zipSink, getRequestForFullFetch(), "admin", hostName, requestingIP);
+
+        Assert.assertNull(result.getData());
+
+        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+        ZipSource zipSource = new ZipSource(bais);
+
+        assertNotNull(exportService);
+        assertNotNull(zipSource.getCreationOrder());
+        Assert.assertFalse(zipSource.hasNext());
+    }
+
+    @Test
+    public void requestingEntityFoundDefaultFetch_ContainsData() throws Exception {
+        ZipSource source = runExportWithParameters(
+                getRequestForDept(false, "", false, ""));
+        verifyExportForHrData(source);
+    }
+
+    @Test
+    public void requestingHrEntityWithMatchTypeContains_ContainsData() throws Exception {
+        ZipSource source = runExportWithParameters(
+                getRequestForDept(false, "", true, "CONTAINS"));
+        verifyExportForHrData(source);
+    }
+
+    @Test
+    public void requestingHrEntityWithMatchTypeEndsWith_ContainsData() throws Exception {
+        ZipSource source = runExportWithParameters(
+                getRequestForDept(false, "", true, "ENDSWITH"));
+        verifyExportForHrData(source);
+    }
+
+    @Test
+    public void requestingDeptEntityFoundFullFetch_ContainsData() throws Exception {
+        ZipSource source = runExportWithParameters(
+                getRequestForDept(true, "FULL", false, ""));
+        verifyExportForHrData(source);
+    }
+
+    @Test
+    public void requestingDeptEntityFoundConnectedFetch_ContainsData() throws Exception {
+        ZipSource source = runExportWithParameters(
+                getRequestForDept(true, "CONNECTED", false, ""));
+        verifyExportForHrDataForConnected(source);
+    }
+
+    @Test
+    public void requestingEmployeeEntityFoundConnectedFetch_ContainsData() throws Exception {
+        ZipSource zipSource = runExportWithParameters(getRequestForEmployee());
+        verifyExportForEmployeeData(zipSource);
+    }
+
+    @Test
+    public void verifyOverallStatus() throws Exception {
+
+//        ExportService service = new ExportService(typeRegistry);
+        assertEquals(AtlasExportResult.OperationStatus.FAIL, exportService.getOverallOperationStatus());
+
+        assertEquals(AtlasExportResult.OperationStatus.SUCCESS, exportService.getOverallOperationStatus(AtlasExportResult.OperationStatus.SUCCESS));
+
+        assertEquals(AtlasExportResult.OperationStatus.SUCCESS, exportService.getOverallOperationStatus(
+                                AtlasExportResult.OperationStatus.SUCCESS,
+                                AtlasExportResult.OperationStatus.SUCCESS,
+                                AtlasExportResult.OperationStatus.SUCCESS));
+
+        assertEquals(AtlasExportResult.OperationStatus.PARTIAL_SUCCESS, exportService.getOverallOperationStatus(
+                AtlasExportResult.OperationStatus.FAIL,
+                AtlasExportResult.OperationStatus.PARTIAL_SUCCESS,
+                AtlasExportResult.OperationStatus.SUCCESS));
+
+        assertEquals(AtlasExportResult.OperationStatus.PARTIAL_SUCCESS, exportService.getOverallOperationStatus(
+                AtlasExportResult.OperationStatus.FAIL,
+                AtlasExportResult.OperationStatus.FAIL,
+                AtlasExportResult.OperationStatus.PARTIAL_SUCCESS));
+
+        assertEquals(AtlasExportResult.OperationStatus.FAIL, exportService.getOverallOperationStatus(
+                AtlasExportResult.OperationStatus.FAIL,
+                AtlasExportResult.OperationStatus.FAIL,
+                AtlasExportResult.OperationStatus.FAIL));
+    }
+
+    @Test
+    public void requestingExportOfNonExistentEntity_ReturnsFailure() throws Exception {
+        AtlasExportRequest request = getRequestForEmployee();
+        tamperEmployeeRequest(request);
+        ZipSource zipSource = runExportWithParameters(request);
+
+        assertNotNull(zipSource.getCreationOrder());
+        assertEquals(zipSource.getCreationOrder().size(), 0);
+        assertEquals(AtlasExportResult.OperationStatus.FAIL, zipSource.getExportResult().getOperationStatus());
+    }
+
+    private void tamperEmployeeRequest(AtlasExportRequest request) {
+        AtlasObjectId objectId = request.getItemsToExport().get(0);
+        objectId.getUniqueAttributes().remove("name");
+        objectId.getUniqueAttributes().put("qualifiedName", "XXX@121");
+    }
+
+    private void verifyExportForEmployeeData(ZipSource zipSource) throws AtlasBaseException {
+        final List<String> expectedEntityTypes = Arrays.asList(new String[]{"Manager", "Employee", "Department"});
+
+        assertNotNull(zipSource.getCreationOrder());
+        assertEquals(zipSource.getCreationOrder().size(), 2);
+        assertTrue(zipSource.hasNext());
+
+        while (zipSource.hasNext()) {
+            AtlasEntity entity = zipSource.next();
+
+            assertNotNull(entity);
+            assertEquals(AtlasEntity.Status.ACTIVE, entity.getStatus());
+            assertTrue(expectedEntityTypes.contains(entity.getTypeName()));
+        }
+
+        verifyTypeDefs(zipSource);
+    }
+
+    private void verifyExportForHrData(ZipSource zipSource) throws IOException, AtlasBaseException {
+        assertNotNull(zipSource.getCreationOrder());
+        assertTrue(zipSource.getCreationOrder().size() == 1);
+        assertTrue(zipSource.hasNext());
+
+        AtlasEntity entity = zipSource.next();
+
+        assertNotNull(entity);
+        assertTrue(entity.getTypeName().equals("Department"));
+        assertEquals(entity.getStatus(), AtlasEntity.Status.ACTIVE);
+        verifyTypeDefs(zipSource);
+    }
+
+    private void verifyExportForHrDataForConnected(ZipSource zipSource) throws IOException, AtlasBaseException {
+        assertNotNull(zipSource.getCreationOrder());
+        assertTrue(zipSource.getCreationOrder().size() == 2);
+        assertTrue(zipSource.hasNext());
+
+        AtlasEntity entity = zipSource.next();
+
+        assertNotNull(entity);
+        assertTrue(entity.getTypeName().equals("Department"));
+        assertEquals(entity.getStatus(), AtlasEntity.Status.ACTIVE);
+        verifyTypeDefs(zipSource);
+    }
+
+    private void verifyTypeDefs(ZipSource zipSource) throws AtlasBaseException {
+        assertEquals(zipSource.getTypesDef().getEnumDefs().size(), 1);
+        assertEquals(zipSource.getTypesDef().getClassificationDefs().size(), 0);
+        assertEquals(zipSource.getTypesDef().getStructDefs().size(), 1);
+        assertEquals(zipSource.getTypesDef().getEntityDefs().size(), 4);
+    }
+}
diff --git a/repository/src/test/java/org/apache/atlas/repository/impexp/ImportServiceTest.java b/repository/src/test/java/org/apache/atlas/repository/impexp/ImportServiceTest.java
new file mode 100644
index 0000000..b24774d
--- /dev/null
+++ b/repository/src/test/java/org/apache/atlas/repository/impexp/ImportServiceTest.java
@@ -0,0 +1,224 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.repository.impexp;
+
+import com.google.inject.Inject;
+import org.apache.atlas.AtlasErrorCode;
+import org.apache.atlas.RequestContextV1;
+import org.apache.atlas.TestModules;
+import org.apache.atlas.TestUtilsV2;
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.impexp.AtlasImportRequest;
+import org.apache.atlas.store.AtlasTypeDefStore;
+import org.apache.atlas.type.AtlasClassificationType;
+import org.apache.atlas.type.AtlasTypeRegistry;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.ITestContext;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.apache.atlas.repository.impexp.ZipFileResourceTestUtils.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
+@Guice(modules = TestModules.TestOnlyModule.class)
+public class ImportServiceTest {
+    private static final Logger LOG = LoggerFactory.getLogger(ImportServiceTest.class);
+    private final ImportService importService;
+
+    @Inject
+    AtlasTypeRegistry typeRegistry;
+
+    @Inject
+    private AtlasTypeDefStore typeDefStore;
+
+    @Inject
+    public ImportServiceTest(ImportService importService) {
+        this.importService = importService;
+    }
+
+    @BeforeTest
+    public void setupTest() {
+        RequestContextV1.clear();
+        RequestContextV1.get().setUser(TestUtilsV2.TEST_USER);
+    }
+
+    @DataProvider(name = "sales")
+    public static Object[][] getDataFromQuickStart_v1_Sales(ITestContext context) throws IOException {
+        return getZipSource("sales-v1-full.zip");
+    }
+
+    @Test(dataProvider = "sales")
+    public void importDB1(ZipSource zipSource) throws AtlasBaseException, IOException {
+        loadBaseModel();
+        runAndVerifyQuickStart_v1_Import(importService, zipSource);
+    }
+
+    @DataProvider(name = "reporting")
+    public static Object[][] getDataFromReporting() throws IOException {
+        return getZipSource("reporting-v1-full.zip");
+    }
+
+    @Test(dataProvider = "reporting")
+    public void importDB2(ZipSource zipSource) throws AtlasBaseException, IOException {
+        loadBaseModel();
+        runAndVerifyQuickStart_v1_Import(importService, zipSource);
+    }
+
+    private void loadBaseModel() throws IOException, AtlasBaseException {
+        loadModelFromJson("0000-Area0/0010-base_model.json", typeDefStore, typeRegistry);
+    }
+
+    @DataProvider(name = "logging")
+    public static Object[][] getDataFromLogging(ITestContext context) throws IOException {
+        return getZipSource("logging-v1-full.zip");
+    }
+
+    @Test(dataProvider = "logging")
+    public void importDB3(ZipSource zipSource) throws AtlasBaseException, IOException {
+        loadBaseModel();
+        runAndVerifyQuickStart_v1_Import(importService, zipSource);
+    }
+
+    @DataProvider(name = "salesNewTypeAttrs")
+    public static Object[][] getDataFromSalesNewTypeAttrs(ITestContext context) throws IOException {
+        return getZipSource("salesNewTypeAttrs.zip");
+    }
+
+    @Test(dataProvider = "salesNewTypeAttrs", dependsOnMethods = "importDB1")
+    public void importDB4(ZipSource zipSource) throws AtlasBaseException, IOException {
+        loadBaseModel();
+        runImportWithParameters(importService, getDefaultImportRequest(), zipSource);
+    }
+
+    @DataProvider(name = "salesNewTypeAttrs-next")
+    public static Object[][] getDataFromSalesNewTypeAttrsNext(ITestContext context) throws IOException {
+        return getZipSource("salesNewTypeAttrs-next.zip");
+    }
+
+
+    @Test(dataProvider = "salesNewTypeAttrs-next", dependsOnMethods = "importDB4")
+    public void importDB5(ZipSource zipSource) throws AtlasBaseException, IOException {
+        final String newEnumDefName = "database_action";
+
+        assertNotNull(typeDefStore.getEnumDefByName(newEnumDefName));
+
+        AtlasImportRequest request = getDefaultImportRequest();
+        Map<String, String> options = new HashMap<>();
+        options.put("updateTypeDefinition", "false");
+        request.setOptions(options);
+
+        runImportWithParameters(importService, request, zipSource);
+        assertNotNull(typeDefStore.getEnumDefByName(newEnumDefName));
+        assertEquals(typeDefStore.getEnumDefByName(newEnumDefName).getElementDefs().size(), 4);
+    }
+
+    @Test(dataProvider = "salesNewTypeAttrs-next", dependsOnMethods = "importDB4")
+    public void importDB6(ZipSource zipSource) throws AtlasBaseException, IOException {
+        final String newEnumDefName = "database_action";
+
+        assertNotNull(typeDefStore.getEnumDefByName(newEnumDefName));
+
+        AtlasImportRequest request = getDefaultImportRequest();
+        Map<String, String> options = new HashMap<>();
+        options.put("updateTypeDefinition", "true");
+        request.setOptions(options);
+
+        runImportWithParameters(importService, request, zipSource);
+        assertNotNull(typeDefStore.getEnumDefByName(newEnumDefName));
+        assertEquals(typeDefStore.getEnumDefByName(newEnumDefName).getElementDefs().size(), 8);
+    }
+
+    @DataProvider(name = "ctas")
+    public static Object[][] getDataFromCtas(ITestContext context) throws IOException {
+        return getZipSource("ctas.zip");
+    }
+
+    @Test(dataProvider = "ctas")
+    public void importCTAS(ZipSource zipSource) throws IOException, AtlasBaseException {
+        loadBaseModel();
+        loadHiveModel();
+
+        runImportWithNoParameters(importService, zipSource);
+    }
+
+    @DataProvider(name = "hdfs_path1")
+    public static Object[][] getDataFromHdfsPath1(ITestContext context) throws IOException {
+        return getZipSource("hdfs_path1.zip");
+    }
+
+
+    @Test(dataProvider = "hdfs_path1", expectedExceptions = AtlasBaseException.class)
+    public void importHdfs_path1(ZipSource zipSource) throws IOException, AtlasBaseException {
+        loadBaseModel();
+        loadFsModel();
+        loadModelFromResourcesJson("tag1.json", typeDefStore, typeRegistry);
+
+        try {
+            runImportWithNoParameters(importService, zipSource);
+        } catch (AtlasBaseException e) {
+            assertEquals(e.getAtlasErrorCode(), AtlasErrorCode.INVALID_IMPORT_ATTRIBUTE_TYPE_CHANGED);
+            AtlasClassificationType tag1 = typeRegistry.getClassificationTypeByName("tag1");
+            assertNotNull(tag1);
+            assertEquals(tag1.getAllAttributes().size(), 2);
+            throw e;
+        }
+    }
+
+    @Test
+    public void importServiceProcessesIOException() {
+        ImportService importService = new ImportService(typeDefStore, typeRegistry, null);
+        AtlasImportRequest req = mock(AtlasImportRequest.class);
+
+        Answer<Map> answer = new Answer<Map>() {
+            @Override
+            public Map answer(InvocationOnMock invocationOnMock) throws Throwable {
+                throw new IOException("file is read only");
+            }
+        };
+
+        when(req.getFileName()).thenReturn("some-file.zip");
+        when(req.getOptions()).thenAnswer(answer);
+
+        try {
+            importService.run(req, "a", "b", "c");
+        }
+        catch (AtlasBaseException ex) {
+            assertEquals(ex.getAtlasErrorCode().getErrorCode(), AtlasErrorCode.INVALID_PARAMETERS.getErrorCode());
+        }
+    }
+
+    private void loadFsModel() throws IOException, AtlasBaseException {
+        loadModelFromJson("1000-Hadoop/1020-fs_model.json", typeDefStore, typeRegistry);
+    }
+
+    private void loadHiveModel() throws IOException, AtlasBaseException {
+        loadModelFromJson("1000-Hadoop/1030-hive_model.json", typeDefStore, typeRegistry);
+    }
+}
diff --git a/repository/src/test/java/org/apache/atlas/repository/impexp/ImportServiceTestUtils.java b/repository/src/test/java/org/apache/atlas/repository/impexp/ImportServiceTestUtils.java
new file mode 100644
index 0000000..7289512
--- /dev/null
+++ b/repository/src/test/java/org/apache/atlas/repository/impexp/ImportServiceTestUtils.java
@@ -0,0 +1,116 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.repository.impexp;
+
+import com.google.common.collect.Sets;
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.impexp.AtlasExportResult;
+import org.apache.atlas.model.impexp.AtlasImportRequest;
+import org.apache.atlas.model.impexp.AtlasImportResult;
+import org.apache.atlas.model.typedef.AtlasTypesDef;
+import org.apache.atlas.repository.store.bootstrap.AtlasTypeDefStoreInitializer;
+import org.apache.atlas.store.AtlasTypeDefStore;
+import org.apache.atlas.type.AtlasType;
+import org.apache.atlas.type.AtlasTypeRegistry;
+import org.testng.Assert;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class ImportServiceTestUtils {
+
+    public static void verifyImportedEntities(List<String> creationOrder, List<String> processedEntities) {
+        Set<String> lhs = com.google.common.collect.Sets.newHashSet(creationOrder);
+        Set<String> rhs = com.google.common.collect.Sets.newHashSet(processedEntities);
+        Set<String> difference = Sets.difference(lhs, rhs);
+
+        Assert.assertNotNull(difference);
+        Assert.assertEquals(difference.size(), 0);
+    }
+
+    public static void verifyImportedMetrics(AtlasExportResult exportResult, AtlasImportResult importResult) {
+        Map<String, Integer> metricsForCompare = getImportMetricsForCompare(importResult);
+        for (Map.Entry<String, Integer> entry : exportResult.getMetrics().entrySet()) {
+            if(entry.getKey().startsWith("entity") == false ||
+                    entry.getKey().contains("withExtInfo") ||
+                    entry.getKey().contains("Column") ||
+                    entry.getKey().contains("StorageDesc")) continue;
+
+            Assert.assertTrue(metricsForCompare.containsKey(entry.getKey()));
+            Assert.assertEquals(entry.getValue(), metricsForCompare.get(entry.getKey()));
+        }
+    }
+
+    private static Map<String,Integer> getImportMetricsForCompare(AtlasImportResult result) {
+        Map<String, Integer> r = new HashMap<>();
+        for (Map.Entry<String, Integer> entry : result.getMetrics().entrySet()) {
+            r.put(entry.getKey().replace(":updated", "").replace(":created", ""), entry.getValue());
+        }
+
+        return r;
+    }
+
+
+    public static void loadModelFromJson(String fileName, AtlasTypeDefStore typeDefStore, AtlasTypeRegistry typeRegistry) throws IOException, AtlasBaseException {
+        AtlasTypesDef typesFromJson = getAtlasTypesDefFromFile(fileName);
+        createTypesAsNeeded(typesFromJson, typeDefStore, typeRegistry);
+    }
+
+    private static void createTypesAsNeeded(AtlasTypesDef typesFromJson, AtlasTypeDefStore typeDefStore, AtlasTypeRegistry typeRegistry) throws AtlasBaseException {
+        AtlasTypesDef typesToCreate = AtlasTypeDefStoreInitializer.getTypesToCreate(typesFromJson, typeRegistry);
+
+        if (!typesToCreate.isEmpty()) {
+            typeDefStore.createTypesDef(typesToCreate);
+        }
+    }
+
+    private static AtlasTypesDef getAtlasTypesDefFromFile(String fileName) throws IOException {
+        String sampleTypes = ZipFileResourceTestUtils.getModelJson(fileName);
+        return AtlasType.fromJson(sampleTypes, AtlasTypesDef.class);
+    }
+
+    public static AtlasImportRequest getDefaultImportRequest() {
+        return new AtlasImportRequest();
+    }
+
+
+    public static AtlasImportResult runImportWithParameters(ImportService importService, AtlasImportRequest request, ZipSource source) throws AtlasBaseException, IOException {
+        final String requestingIP = "1.0.0.0";
+        final String hostName = "localhost";
+        final String userName = "admin";
+
+        AtlasImportResult result = importService.run(source, request, userName, hostName, requestingIP);
+        Assert.assertEquals(result.getOperationStatus(), AtlasImportResult.OperationStatus.SUCCESS);
+        return result;
+    }
+
+    public static void runAndVerifyQuickStart_v1_Import(ImportService importService, ZipSource zipSource) throws AtlasBaseException, IOException {
+        AtlasExportResult exportResult = zipSource.getExportResult();
+        List<String> creationOrder = zipSource.getCreationOrder();
+
+        AtlasImportRequest request = getDefaultImportRequest();
+        AtlasImportResult result = runImportWithParameters(importService, request, zipSource);
+
+        Assert.assertNotNull(result);
+        verifyImportedMetrics(exportResult, result);
+        verifyImportedEntities(creationOrder, result.getProcessedEntities());
+    }
+}
diff --git a/repository/src/test/java/org/apache/atlas/repository/impexp/ImportTransformerJSONTest.java b/repository/src/test/java/org/apache/atlas/repository/impexp/ImportTransformerJSONTest.java
new file mode 100644
index 0000000..7044e71
--- /dev/null
+++ b/repository/src/test/java/org/apache/atlas/repository/impexp/ImportTransformerJSONTest.java
@@ -0,0 +1,47 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.repository.impexp;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+
+import static org.testng.Assert.*;
+
+public class ImportTransformerJSONTest {
+
+
+    @Test
+    public void createAtlasImportTransformFromJson() throws Exception {
+        String hiveTableType  = "hive_table";
+        String qualifiedName  = "qualifiedName";
+        String jsonTransforms = "{ \"hive_table\": { \"qualifiedName\":[ \"lowercase\", \"replace:@cl1:@cl2\" ] } }";
+
+        ImportTransforms transforms = ImportTransforms.fromJson(jsonTransforms);
+
+        assertNotNull(transforms);
+        assertEquals(transforms.getTransforms().entrySet().size(), 1);
+        assertEquals(transforms.getTransforms().get(hiveTableType).entrySet().size(), 1);
+        assertEquals(transforms.getTransforms().get(hiveTableType).get(qualifiedName).size(), 2);
+        Assert.assertEquals(transforms.getTransforms().get(hiveTableType).get(qualifiedName).get(0).getTransformType(), "lowercase");
+        assertEquals(transforms.getTransforms().get(hiveTableType).get(qualifiedName).get(1).getTransformType(), "replace");
+        assertTrue(transforms.getTransforms().get(hiveTableType).get(qualifiedName).get(1) instanceof ImportTransformer.Replace);
+        assertEquals(((ImportTransformer.Replace)transforms.getTransforms().get(hiveTableType).get(qualifiedName).get(1)).getToFindStr(), "@cl1");
+        assertEquals(((ImportTransformer.Replace)transforms.getTransforms().get(hiveTableType).get(qualifiedName).get(1)).getReplaceStr(), "@cl2");
+    }
+}
diff --git a/repository/src/test/java/org/apache/atlas/repository/impexp/ImportTransformerTest.java b/repository/src/test/java/org/apache/atlas/repository/impexp/ImportTransformerTest.java
new file mode 100644
index 0000000..7ce34c8
--- /dev/null
+++ b/repository/src/test/java/org/apache/atlas/repository/impexp/ImportTransformerTest.java
@@ -0,0 +1,131 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.repository.impexp;
+
+import org.apache.atlas.exception.AtlasBaseException;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+public class ImportTransformerTest {
+
+    @Test
+    public void createWithCorrectParameters() throws AtlasBaseException, IllegalAccessException {
+        String param1 = "@cl1";
+        String param2 = "@cl2";
+
+        ImportTransformer e = ImportTransformer.getTransformer(String.format("%s:%s:%s", "replace", param1, param2));
+
+        assertTrue(e instanceof ImportTransformer.Replace);
+        assertEquals(((ImportTransformer.Replace)e).getToFindStr(), param1);
+        assertEquals(((ImportTransformer.Replace)e).getReplaceStr(), param2);
+    }
+
+    @Test
+    public void createSeveralWithCorrectParameters() throws AtlasBaseException, IllegalAccessException {
+        String param1 = "@cl1";
+        String param2 = "@cl2";
+
+        ImportTransformer e1 = ImportTransformer.getTransformer(String.format("%s:%s:%s", "replace", param1, param2));
+        ImportTransformer e2 = ImportTransformer.getTransformer(String.format("replace:tt1:tt2"));
+
+        assertTrue(e1 instanceof ImportTransformer.Replace);
+        assertEquals(((ImportTransformer.Replace)e1).getToFindStr(), param1);
+        assertEquals(((ImportTransformer.Replace)e1).getReplaceStr(), param2);
+
+        assertTrue(e2 instanceof ImportTransformer.Replace);
+        assertEquals(((ImportTransformer.Replace)e2).getToFindStr(), "tt1");
+        assertEquals(((ImportTransformer.Replace)e2).getReplaceStr(), "tt2");
+    }
+
+    @Test
+    public void createWithDefaultParameters() throws AtlasBaseException {
+        ImportTransformer e1 = ImportTransformer.getTransformer("replace:@cl1");
+        ImportTransformer e2 = ImportTransformer.getTransformer("replace");
+
+        assertTrue(e1 instanceof ImportTransformer.Replace);
+        assertEquals(((ImportTransformer.Replace)e1).getToFindStr(), "@cl1");
+        assertEquals(((ImportTransformer.Replace)e1).getReplaceStr(), "");
+
+        assertTrue(e2 instanceof ImportTransformer.Replace);
+        assertEquals(((ImportTransformer.Replace)e2).getToFindStr(), "");
+        assertEquals(((ImportTransformer.Replace)e2).getReplaceStr(), "");
+    }
+
+    @Test
+    public void applyLowercaseTransformer() throws AtlasBaseException {
+        ImportTransformer e = ImportTransformer.getTransformer("lowercase");
+
+        assertEquals(e.apply("@CL1"), "@cl1");
+        assertEquals(e.apply("@cl1"), "@cl1");
+        assertEquals(e.apply(""), ""); // empty string
+        assertEquals(e.apply(null), null); // null value: no change
+        assertEquals(e.apply(Integer.valueOf(5)), Integer.valueOf(5)); // non-string value: no change
+    }
+
+    @Test
+    public void applyUppercaseTransformer() throws AtlasBaseException {
+        ImportTransformer e = ImportTransformer.getTransformer("uppercase");
+
+        assertEquals(e.apply("@CL1"), "@CL1");
+        assertEquals(e.apply("@cl1"), "@CL1");
+        assertEquals(e.apply(""), ""); // empty string
+        assertEquals(e.apply(null), null); // null value: no change
+        assertEquals(e.apply(Integer.valueOf(5)), Integer.valueOf(5)); // non-string value: no change
+    }
+
+    @Test
+    public void applyReplaceTransformer1() throws AtlasBaseException {
+        ImportTransformer e = ImportTransformer.getTransformer("replace:@cl1:@cl2");
+
+        assertEquals(e.apply("@cl1"), "@cl2");
+        assertEquals(e.apply("default@cl1"), "default@cl2");
+        assertEquals(e.apply("@cl11"), "@cl21");
+        assertEquals(e.apply("@cl2"), "@cl2");
+        assertEquals(e.apply(""), ""); // empty string
+        assertEquals(e.apply(null), null); // null value
+        assertEquals(e.apply(Integer.valueOf(5)), Integer.valueOf(5)); // non-string value: no change
+    }
+
+    @Test
+    public void applyReplaceTransformer2() throws AtlasBaseException {
+        ImportTransformer e = ImportTransformer.getTransformer("replace:@cl1");
+
+        assertEquals(e.apply("@cl1"), "");
+        assertEquals(e.apply("default@cl1"), "default");
+        assertEquals(e.apply("@cl11"), "1");
+        assertEquals(e.apply("@cl2"), "@cl2");
+        assertEquals(e.apply(""), ""); // empty string
+        assertEquals(e.apply(null), null); // null value
+        assertEquals(e.apply(Integer.valueOf(5)), Integer.valueOf(5)); // non-string value: no change
+    }
+
+    @Test
+    public void applyReplaceTransformer3() throws AtlasBaseException {
+        ImportTransformer e = ImportTransformer.getTransformer("replace");
+
+        assertEquals(e.apply("@cl1"), "@cl1");
+        assertEquals(e.apply("default@cl1"), "default@cl1");
+        assertEquals(e.apply("@cl11"), "@cl11");
+        assertEquals(e.apply("@cl2"), "@cl2");
+        assertEquals(e.apply(""), ""); // empty string
+        assertEquals(e.apply(null), null); // null value
+        assertEquals(e.apply(Integer.valueOf(5)), Integer.valueOf(5)); // non-string value: no change
+    }
+}
diff --git a/repository/src/test/java/org/apache/atlas/repository/impexp/ImportTransformsTest.java b/repository/src/test/java/org/apache/atlas/repository/impexp/ImportTransformsTest.java
new file mode 100644
index 0000000..ccedeb1
--- /dev/null
+++ b/repository/src/test/java/org/apache/atlas/repository/impexp/ImportTransformsTest.java
@@ -0,0 +1,151 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.repository.impexp;
+
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.instance.AtlasEntity;
+import org.apache.atlas.model.instance.AtlasEntity.AtlasEntityWithExtInfo;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
+public class ImportTransformsTest {
+    private final String qualifiedName  = "qualifiedName";
+    private final String lowerCaseCL1   = "@cl1";
+    private final String lowerCaseCL2   = "@cl2";
+    private final String jsonTransforms = "{ \"hive_table\": { \"qualifiedName\":[ \"lowercase\", \"replace:@cl1:@cl2\" ] } }";
+
+    private ImportTransforms transform;
+
+    @BeforeTest
+    public void setup() throws AtlasBaseException {
+        transform = ImportTransforms.fromJson(jsonTransforms);
+    }
+
+    @Test
+    public void transformEntityWith2Transforms() throws AtlasBaseException {
+        AtlasEntity entity    = getHiveTableAtlasEntity();
+        String      attrValue = (String) entity.getAttribute(qualifiedName);
+
+        transform.apply(entity);
+
+        assertEquals(entity.getAttribute(qualifiedName), applyDefaultTransform(attrValue));
+    }
+
+    @Test
+    public void transformEntityWithExtInfo() throws AtlasBaseException {
+        addColumnTransform(transform);
+
+        AtlasEntityWithExtInfo entityWithExtInfo = getAtlasEntityWithExtInfo();
+        AtlasEntity            entity            = entityWithExtInfo.getEntity();
+        String                 attrValue         = (String) entity.getAttribute(qualifiedName);
+        String[]               expectedValues    = getExtEntityExpectedValues(entityWithExtInfo);
+
+        transform.apply(entityWithExtInfo);
+
+        assertEquals(entityWithExtInfo.getEntity().getAttribute(qualifiedName), applyDefaultTransform(attrValue));
+
+        for (int i = 0; i < expectedValues.length; i++) {
+            assertEquals(entityWithExtInfo.getReferredEntities().get(Integer.toString(i)).getAttribute(qualifiedName), expectedValues[i]);
+        }
+    }
+
+    @Test
+    public void transformEntityWithExtInfoNullCheck() throws AtlasBaseException {
+        addColumnTransform(transform);
+
+        AtlasEntityWithExtInfo entityWithExtInfo = getAtlasEntityWithExtInfo();
+
+        entityWithExtInfo.setReferredEntities(null);
+
+        AtlasEntityWithExtInfo transformedEntityWithExtInfo = transform.apply(entityWithExtInfo);
+
+        assertNotNull(transformedEntityWithExtInfo);
+        assertEquals(entityWithExtInfo.getEntity().getGuid(), transformedEntityWithExtInfo.getEntity().getGuid());
+    }
+
+    private String[] getExtEntityExpectedValues(AtlasEntityWithExtInfo entityWithExtInfo) {
+        String[] ret = new String[entityWithExtInfo.getReferredEntities().size()];
+
+        for (int i = 0; i < ret.length; i++) {
+            String attrValue = (String) entityWithExtInfo.getReferredEntities().get(Integer.toString(i)).getAttribute(qualifiedName);
+
+            ret[i] = attrValue.replace(lowerCaseCL1, lowerCaseCL2);
+        }
+
+        return ret;
+    }
+
+    private void addColumnTransform(ImportTransforms transform) throws AtlasBaseException {
+        Map<String, List<ImportTransformer>> tr     = new HashMap<>();
+        List<ImportTransformer>              trList = new ArrayList<>();
+
+        trList.add(ImportTransformer.getTransformer(String.format("replace:%s:%s", lowerCaseCL1, lowerCaseCL2)));
+
+        tr.put(qualifiedName, trList);
+
+        transform.getTransforms().put("hive_column", tr);
+    }
+
+    private String applyDefaultTransform(String attrValue) {
+        return attrValue.toLowerCase().replace(lowerCaseCL1, lowerCaseCL2);
+    }
+
+    private AtlasEntity getHiveTableAtlasEntity() {
+        AtlasEntity entity = new AtlasEntity("hive_table");
+
+        Map<String, Object> attributes = new HashMap<>();
+        attributes.put(qualifiedName, "TABLE1.default" + lowerCaseCL1);
+        attributes.put("dbname", "someDB");
+        attributes.put("name", "somename");
+
+        entity.setAttributes(attributes);
+        return entity;
+    }
+
+    private AtlasEntity getHiveColumnAtlasEntity(int index) {
+        AtlasEntity entity = new AtlasEntity("hive_column");
+
+        Map<String, Object> attributes = new HashMap<>();
+        attributes.put(qualifiedName, String.format("col%s.TABLE1.default@cl1", index));
+        attributes.put("name", "col" + index);
+
+        entity.setAttributes(attributes);
+        return entity;
+    }
+
+    private AtlasEntityWithExtInfo getAtlasEntityWithExtInfo() {
+        AtlasEntityWithExtInfo ret = new AtlasEntityWithExtInfo(getHiveTableAtlasEntity());
+
+        Map<String, AtlasEntity> referredEntities = new HashMap<>();
+        referredEntities.put("0", getHiveColumnAtlasEntity(1));
+        referredEntities.put("1", getHiveColumnAtlasEntity(2));
+        referredEntities.put("2", getHiveColumnAtlasEntity(3));
+
+        ret.setReferredEntities(referredEntities);
+
+        return ret;
+    }
+}
diff --git a/repository/src/test/java/org/apache/atlas/repository/impexp/TypeAttributeDifferenceTest.java b/repository/src/test/java/org/apache/atlas/repository/impexp/TypeAttributeDifferenceTest.java
new file mode 100644
index 0000000..87cb1d4
--- /dev/null
+++ b/repository/src/test/java/org/apache/atlas/repository/impexp/TypeAttributeDifferenceTest.java
@@ -0,0 +1,150 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.repository.impexp;
+
+import org.apache.atlas.model.typedef.AtlasBaseTypeDef;
+import org.apache.atlas.model.typedef.AtlasEntityDef;
+import org.apache.atlas.model.typedef.AtlasEnumDef;
+import org.apache.atlas.model.typedef.AtlasStructDef;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TypeAttributeDifferenceTest {
+    private TypeAttributeDifference typeAttributeDifference;
+
+    @BeforeClass
+    public void setup() {
+        typeAttributeDifference = new TypeAttributeDifference(null, null);
+    }
+
+    private List<AtlasEnumDef.AtlasEnumElementDef> getEnumElementDefs(int startIndex, String... names) {
+        int i = startIndex;
+        List<AtlasEnumDef.AtlasEnumElementDef> list = new ArrayList<>();
+        for (String s: names) {
+            list.add(new AtlasEnumDef.AtlasEnumElementDef(s, s, i++));
+        }
+
+        return list;
+    }
+
+    private List<AtlasStructDef.AtlasAttributeDef> getAtlasAttributeDefs(String... names) {
+        List<AtlasStructDef.AtlasAttributeDef> list = new ArrayList<>();
+        for (String s : names) {
+            list.add(new AtlasStructDef.AtlasAttributeDef(s, AtlasBaseTypeDef.ATLAS_TYPE_STRING));
+        }
+
+        return list;
+    }
+
+    private AtlasEntityDef getAtlasEntityDefWithAttributes(String... attributeNames) {
+        AtlasEntityDef e = new AtlasEntityDef();
+        for (AtlasStructDef.AtlasAttributeDef a : getAtlasAttributeDefs(attributeNames)) {
+            e.addAttribute(a);
+        }
+
+        return e;
+    }
+
+    @Test
+    public void entityDefWithNoAttributes() throws Exception {
+        AtlasEntityDef existing = new AtlasEntityDef();
+        AtlasEntityDef incoming = new AtlasEntityDef();
+        List<AtlasStructDef.AtlasAttributeDef> expectedAttributes = new ArrayList<>();
+        List<AtlasStructDef.AtlasAttributeDef> actualAttributes = invokeGetAttributesAbsentInExisting(existing, incoming);
+
+        Assert.assertEquals(actualAttributes, expectedAttributes);
+    }
+
+    private List<AtlasStructDef.AtlasAttributeDef> invokeGetAttributesAbsentInExisting(AtlasStructDef existing, AtlasStructDef incoming) throws Exception {
+        return typeAttributeDifference.getElementsAbsentInExisting(existing, incoming);
+    }
+
+    private List<AtlasEnumDef.AtlasEnumElementDef> invokeGetAttributesAbsentInExisting(AtlasEnumDef existing, AtlasEnumDef incoming) throws Exception {
+        return typeAttributeDifference.getElementsAbsentInExisting(existing, incoming);
+    }
+
+    private AtlasEnumDef getAtlasEnumWithAttributes(String... elements) {
+        AtlasEnumDef enumDef = new AtlasEnumDef();
+        for (AtlasEnumDef.AtlasEnumElementDef ed : getEnumElementDefs(0, elements)) {
+            enumDef.addElement(ed);
+        }
+
+        return enumDef;
+    }
+
+    @Test
+    public void bothSame_DifferenceIsEmptyList() throws Exception {
+        AtlasEntityDef existing = getAtlasEntityDefWithAttributes("name", "qualifiedName");
+        AtlasEntityDef incoming = getAtlasEntityDefWithAttributes("name", "qualifiedName");
+
+        List<AtlasStructDef.AtlasAttributeDef> expectedAttributes = getAtlasAttributeDefs();
+        List<AtlasStructDef.AtlasAttributeDef> actualAttributes = invokeGetAttributesAbsentInExisting(existing, incoming);
+
+        Assert.assertEquals(actualAttributes, expectedAttributes);
+    }
+
+    @Test
+    public void different_ReturnsDifference() throws Exception {
+        AtlasEntityDef existing = getAtlasEntityDefWithAttributes("name");
+        AtlasEntityDef incoming = getAtlasEntityDefWithAttributes("name", "qualifiedName");
+        List<AtlasStructDef.AtlasAttributeDef> expectedAttributes = getAtlasAttributeDefs( "qualifiedName");
+
+        List<AtlasStructDef.AtlasAttributeDef> actualAttributes = invokeGetAttributesAbsentInExisting(existing, incoming);
+        Assert.assertEquals(actualAttributes, expectedAttributes);
+    }
+
+    @Test
+    public void differentSubset_ReturnsDifference() throws Exception {
+        AtlasEntityDef existing = getAtlasEntityDefWithAttributes("name", "qualifiedName");
+        AtlasEntityDef incoming = getAtlasEntityDefWithAttributes("name");
+        List<AtlasStructDef.AtlasAttributeDef> actualAttributes = invokeGetAttributesAbsentInExisting(existing, incoming);
+
+        List<AtlasStructDef.AtlasAttributeDef> expectedAttributes = getAtlasAttributeDefs();
+        Assert.assertEquals(actualAttributes, expectedAttributes);
+    }
+
+    @Test
+    public void differentEnumDef_ReturnsDifference () throws Exception {
+        AtlasEnumDef existing = getAtlasEnumWithAttributes("Alpha", "Bravo");
+        AtlasEnumDef incoming = getAtlasEnumWithAttributes("Alpha", "Bravo", "Delta", "Echo");
+        List<AtlasEnumDef.AtlasEnumElementDef> actualAttributes = invokeGetAttributesAbsentInExisting(existing, incoming);
+
+        List<AtlasEnumDef.AtlasEnumElementDef> expectedAttributes = getEnumElementDefs(2, "Delta", "Echo");
+        Assert.assertEquals(actualAttributes, expectedAttributes);
+    }
+
+    @Test
+    public void differentEnumDefs_ReturnsDifference () throws Exception {
+        AtlasEnumDef existing = getAtlasEnumWithAttributes("Alpha", "Bravo");
+        AtlasEnumDef incoming = getAtlasEnumWithAttributes("Alpha", "Bravo", "Delta", "Echo");
+        boolean ret = invokeUpdate(existing, incoming);
+
+        List<AtlasEnumDef.AtlasEnumElementDef> expectedAttributes = getEnumElementDefs(0, "Alpha", "Bravo", "Delta", "Echo");
+
+        Assert.assertTrue(ret, "Update took place");
+        Assert.assertEquals(existing.getElementDefs(), expectedAttributes);
+    }
+
+    private boolean invokeUpdate(AtlasEnumDef existing, AtlasEnumDef incoming) throws Exception {
+        return typeAttributeDifference.addElements(existing, incoming);
+    }
+}
diff --git a/repository/src/test/java/org/apache/atlas/repository/impexp/UniqueListTest.java b/repository/src/test/java/org/apache/atlas/repository/impexp/UniqueListTest.java
new file mode 100644
index 0000000..93aa518
--- /dev/null
+++ b/repository/src/test/java/org/apache/atlas/repository/impexp/UniqueListTest.java
@@ -0,0 +1,69 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.repository.impexp;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+public class UniqueListTest {
+    private final String firstElement = "firstElement";
+    private ExportService.UniqueList<String> uniqueList;
+
+    @BeforeClass
+    public void setup() {
+        uniqueList = new ExportService.UniqueList();
+        uniqueList.add(firstElement);
+        uniqueList.add("def");
+        uniqueList.add("firstElement");
+        uniqueList.add("ghi");
+    }
+
+    @Test
+    public void add3Elements_ListHas2() {
+        assertEquals(3, uniqueList.size());
+    }
+
+    @Test
+    public void addAllList_ListHas2() {
+        ExportService.UniqueList<String> uniqueList2 = new ExportService.UniqueList<>();
+        uniqueList2.addAll(uniqueList);
+
+        assertEquals(3, uniqueList2.size());
+    }
+
+    @Test
+    public void attemptClear_SizeIsZero() {
+        ExportService.UniqueList<String> uniqueList2 = new ExportService.UniqueList<>();
+        uniqueList2.addAll(uniqueList);
+        uniqueList2.clear();
+
+        assertEquals(0, uniqueList2.size());
+    }
+
+    @Test
+    public void attemptOneRemove_SizeIsReduced() {
+        ExportService.UniqueList<String> uniqueList2 = new ExportService.UniqueList<>();
+        uniqueList2.addAll(uniqueList);
+        String removedElement = uniqueList2.remove(0);
+
+        assertEquals(2, uniqueList2.size());
+        assertEquals(firstElement, removedElement);
+    }
+}
diff --git a/repository/src/test/java/org/apache/atlas/repository/impexp/ZipFileResourceTestUtils.java b/repository/src/test/java/org/apache/atlas/repository/impexp/ZipFileResourceTestUtils.java
new file mode 100644
index 0000000..5ab8c01
--- /dev/null
+++ b/repository/src/test/java/org/apache/atlas/repository/impexp/ZipFileResourceTestUtils.java
@@ -0,0 +1,220 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.repository.impexp;
+
+import com.google.common.collect.Sets;
+import org.apache.atlas.RequestContextV1;
+import org.apache.atlas.TestUtilsV2;
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.impexp.AtlasExportResult;
+import org.apache.atlas.model.impexp.AtlasImportRequest;
+import org.apache.atlas.model.impexp.AtlasImportResult;
+import org.apache.atlas.model.typedef.AtlasTypesDef;
+import org.apache.atlas.repository.store.bootstrap.AtlasTypeDefStoreInitializer;
+import org.apache.atlas.store.AtlasTypeDefStore;
+import org.apache.atlas.type.AtlasType;
+import org.apache.atlas.type.AtlasTypeRegistry;
+import org.apache.atlas.utils.TestResourceFileUtils;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+public class ZipFileResourceTestUtils {
+    public static final Logger LOG = LoggerFactory.getLogger(ZipFileResourceTestUtils.class);
+
+    public static FileInputStream getFileInputStream(String fileName) {
+        return TestResourceFileUtils.getFileInputStream(fileName);
+    }
+
+    public static String getModelJson(String fileName) throws IOException {
+        String  ret                 = null;
+        File   topModelsDir         = new File(System.getProperty("user.dir") + "/../addons/models");
+        File[] topModelsDirContents = topModelsDir.exists() ? topModelsDir.listFiles() : null;
+
+        assertTrue(topModelsDirContents != null, topModelsDir.getAbsolutePath() + ": unable to find/read directory");
+        if(topModelsDirContents != null) {
+            Arrays.sort(topModelsDirContents);
+            for (File modelDir : topModelsDirContents) {
+                if (modelDir.exists() && modelDir.isDirectory()) {
+                    ret = getFileContents(modelDir, fileName);
+
+                    if (ret != null) {
+                        break;
+                    }
+                }
+            }
+
+            if (ret == null) {
+                ret = getFileContents(topModelsDir, fileName);
+            }
+
+            assertTrue(ret != null, fileName + ": unable to find model file");
+        } else {
+            throw new IOException("Unable to retrieve model contents.");
+        }
+
+        return ret;
+    }
+
+    public static String getFileContents(File dir, String fileName) throws IOException {
+        if (dir.exists() && dir.isDirectory()) {
+            File file = new File(dir, fileName);
+
+            if (file.exists() && file.isFile()) {
+                return FileUtils.readFileToString(file);
+            }
+        }
+
+        return null;
+    }
+
+    public static String getModelJsonFromResources(String fileName) throws IOException {
+        String filePath = TestResourceFileUtils.getTestFilePath(fileName);
+        File f = new File(filePath);
+        String s = FileUtils.readFileToString(f);
+        assertFalse(StringUtils.isEmpty(s), "Model file read correctly from resources!");
+
+        return s;
+    }
+
+    public static Object[][] getZipSource(String fileName) throws IOException {
+        FileInputStream fs = ZipFileResourceTestUtils.getFileInputStream(fileName);
+
+        return new Object[][]{{new ZipSource(fs)}};
+    }
+
+
+    public static void verifyImportedEntities(List<String> creationOrder, List<String> processedEntities) {
+        Set<String> lhs = com.google.common.collect.Sets.newHashSet(creationOrder);
+        Set<String> rhs = com.google.common.collect.Sets.newHashSet(processedEntities);
+        Set<String> difference = Sets.difference(lhs, rhs);
+
+        assertNotNull(difference);
+        assertEquals(difference.size(), 0);
+    }
+
+    public static void verifyImportedMetrics(AtlasExportResult exportResult, AtlasImportResult importResult) {
+        Map<String, Integer> metricsForCompare = getImportMetricsForCompare(importResult);
+        for (Map.Entry<String, Integer> entry : exportResult.getMetrics().entrySet()) {
+            if(entry.getKey().startsWith("entity") == false ||
+                    entry.getKey().contains("withExtInfo") ||
+                    entry.getKey().contains("Column") ||
+                    entry.getKey().contains("StorageDesc")) continue;
+
+            assertTrue(metricsForCompare.containsKey(entry.getKey()), entry.getKey());
+            assertEquals(entry.getValue(), metricsForCompare.get(entry.getKey()), entry.getKey());
+        }
+    }
+
+    private static Map<String,Integer> getImportMetricsForCompare(AtlasImportResult result) {
+        Map<String, Integer> r = new HashMap<>();
+        for (Map.Entry<String, Integer> entry : result.getMetrics().entrySet()) {
+            r.put(entry.getKey().replace(":updated", "").replace(":created", ""), entry.getValue());
+        }
+
+        return r;
+    }
+
+
+    public static void loadModelFromJson(String fileName, AtlasTypeDefStore typeDefStore, AtlasTypeRegistry typeRegistry) throws IOException, AtlasBaseException {
+        AtlasTypesDef typesFromJson = getAtlasTypesDefFromFile(fileName);
+        createTypesAsNeeded(typesFromJson, typeDefStore, typeRegistry);
+    }
+
+    public static void loadModelFromResourcesJson(String fileName, AtlasTypeDefStore typeDefStore, AtlasTypeRegistry typeRegistry) throws IOException, AtlasBaseException {
+        AtlasTypesDef typesFromJson = getAtlasTypesDefFromResourceFile(fileName);
+        createTypesAsNeeded(typesFromJson, typeDefStore, typeRegistry);
+    }
+
+    private static void createTypesAsNeeded(AtlasTypesDef typesFromJson, AtlasTypeDefStore typeDefStore, AtlasTypeRegistry typeRegistry) throws AtlasBaseException {
+        if(typesFromJson == null) {
+            return;
+        }
+
+        AtlasTypesDef typesToCreate = AtlasTypeDefStoreInitializer.getTypesToCreate(typesFromJson, typeRegistry);
+        if (typesToCreate != null && !typesToCreate.isEmpty()) {
+            typeDefStore.createTypesDef(typesToCreate);
+        }
+    }
+
+    private static AtlasTypesDef getAtlasTypesDefFromFile(String fileName) throws IOException {
+        String sampleTypes = ZipFileResourceTestUtils.getModelJson(fileName);
+        if(sampleTypes == null) return null;
+        return AtlasType.fromJson(sampleTypes, AtlasTypesDef.class);
+    }
+
+    private static AtlasTypesDef getAtlasTypesDefFromResourceFile(String fileName) throws IOException {
+        String sampleTypes = getModelJsonFromResources(fileName);
+        return AtlasType.fromJson(sampleTypes, AtlasTypesDef.class);
+    }
+
+    public static AtlasImportRequest getDefaultImportRequest() {
+        return new AtlasImportRequest();
+    }
+
+
+    public static AtlasImportResult runImportWithParameters(ImportService importService, AtlasImportRequest request, ZipSource source) throws AtlasBaseException, IOException {
+        final String requestingIP = "1.0.0.0";
+        final String hostName = "localhost";
+        final String userName = "admin";
+
+        AtlasImportResult result = importService.run(source, request, userName, hostName, requestingIP);
+        assertEquals(result.getOperationStatus(), AtlasImportResult.OperationStatus.SUCCESS);
+        return result;
+    }
+
+    public static AtlasImportResult runImportWithNoParameters(ImportService importService, ZipSource source) throws AtlasBaseException, IOException {
+        final String requestingIP = "1.0.0.0";
+        final String hostName = "localhost";
+        final String userName = "admin";
+
+        AtlasImportResult result = importService.run(source, userName, hostName, requestingIP);
+        assertEquals(result.getOperationStatus(), AtlasImportResult.OperationStatus.SUCCESS);
+        return result;
+    }
+
+    public static void runAndVerifyQuickStart_v1_Import(ImportService importService, ZipSource zipSource) throws AtlasBaseException, IOException {
+        AtlasExportResult exportResult = zipSource.getExportResult();
+        List<String> creationOrder = zipSource.getCreationOrder();
+
+        RequestContextV1.clear();
+        RequestContextV1.get().setUser(TestUtilsV2.TEST_USER);
+
+        AtlasImportRequest request = getDefaultImportRequest();
+        AtlasImportResult result = runImportWithParameters(importService, request, zipSource);
+
+        assertNotNull(result);
+        verifyImportedMetrics(exportResult, result);
+        verifyImportedEntities(creationOrder, result.getProcessedEntities());
+    }
+}
diff --git a/repository/src/test/java/org/apache/atlas/repository/impexp/ZipSinkTest.java b/repository/src/test/java/org/apache/atlas/repository/impexp/ZipSinkTest.java
new file mode 100644
index 0000000..e8bbeb5
--- /dev/null
+++ b/repository/src/test/java/org/apache/atlas/repository/impexp/ZipSinkTest.java
@@ -0,0 +1,210 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.repository.impexp;
+
+
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.impexp.AtlasExportRequest;
+import org.apache.atlas.model.impexp.AtlasExportResult;
+import org.apache.atlas.model.instance.AtlasEntity;
+import org.apache.atlas.model.instance.AtlasObjectId;
+import org.apache.atlas.type.AtlasType;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import static org.testng.Assert.*;
+
+public class ZipSinkTest {
+    private ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+    private ZipSink zipSink;
+    private List<String> defaultExportOrder = new ArrayList<>(Arrays.asList("a", "b", "c", "d"));
+    private AtlasExportResult defaultExportResult;
+    private String knownEntityGuidFormat = "111-222-333-%s";
+
+
+    private void initZipSinkWithExportOrder() throws AtlasBaseException {
+        zipSink = new ZipSink(byteArrayOutputStream);
+        zipSink.setExportOrder(defaultExportOrder);
+        zipSink.close();
+    }
+
+    private AtlasExportResult getDefaultExportResult() {
+        AtlasExportRequest request = new AtlasExportRequest();
+
+        List<AtlasObjectId> itemsToExport = new ArrayList<>();
+        itemsToExport.add(new AtlasObjectId("hive_db", "qualifiedName", "default"));
+        request.setItemsToExport(itemsToExport);
+
+        defaultExportResult = new AtlasExportResult(request, "admin", "1.0.0.0", "root", 100);
+        return defaultExportResult;
+    }
+
+    private ZipInputStream getZipInputStreamForDefaultExportOrder() throws AtlasBaseException {
+        initZipSinkWithExportOrder();
+
+        ByteArrayInputStream bis = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
+        return new ZipInputStream(bis);
+    }
+
+    private String getZipEntryAsStream(ZipInputStream zis) throws IOException {
+        byte[] buf = new byte[1024];
+        int n = 0;
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        while ((n = zis.read(buf, 0, 1024)) > -1) {
+            bos.write(buf, 0, n);
+        }
+
+        Assert.assertNotNull(bos);
+        return bos.toString();
+    }
+
+    @Test
+    public void correctInit_succeeds() throws AtlasBaseException {
+        initZipSinkWithExportOrder();
+        assertTrue(true);
+        Assert.assertNotNull(zipSink);
+    }
+
+    @Test
+    public void zipWithExactlyOneEntry_succeeds() {
+
+        try {
+            ZipInputStream zis = getZipInputStreamForDefaultExportOrder();
+
+            try {
+                Assert.assertNotNull(zis.getNextEntry());
+                Assert.assertNull(zis.getNextEntry());
+            } catch (IOException e) {
+
+                assertTrue(false);
+            }
+        } catch (AtlasBaseException e) {
+
+            assertTrue(false, "No exception should be thrown.");
+        }
+    }
+
+    @Test
+    public void verifyExportOrderEntryName_verifies() throws AtlasBaseException, IOException {
+
+        ZipInputStream zis = getZipInputStreamForDefaultExportOrder();
+        ZipEntry ze = zis.getNextEntry();
+
+        assertEquals(ze.getName().replace(".json", ""), ZipExportFileNames.ATLAS_EXPORT_ORDER_NAME.toString());
+    }
+
+    @Test
+    public void zipWithExactlyOneEntry_ContentsVerified() throws AtlasBaseException, IOException {
+
+        ZipInputStream zis = getZipInputStreamForDefaultExportOrder();
+        zis.getNextEntry();
+
+        assertEquals(getZipEntryAsStream(zis).replace("\"", "'"), "['a','b','c','d']");
+    }
+
+    @Test
+    public void zipWithExactlyTwoEntries_ContentsVerified() throws AtlasBaseException, IOException {
+
+        ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
+        useZipSinkToCreateEntries(byteOutputStream);
+
+        ByteArrayInputStream bis = new ByteArrayInputStream(byteOutputStream.toByteArray());
+        ZipInputStream zipStream = new ZipInputStream(bis);
+        ZipEntry entry = zipStream.getNextEntry();
+
+        assertEquals(getZipEntryAsStream(zipStream), "[\"a\",\"b\",\"c\",\"d\"]");
+        assertEquals(entry.getName().replace(".json", ""), ZipExportFileNames.ATLAS_EXPORT_ORDER_NAME.toString());
+
+        entry = zipStream.getNextEntry();
+        assertEquals(entry.getName().replace(".json", ""), ZipExportFileNames.ATLAS_EXPORT_INFO_NAME.toString());
+        assertTrue(compareJsonWithObject(getZipEntryAsStream(zipStream), defaultExportResult));
+    }
+
+    @Test
+    public void recordsEntityEntries() throws AtlasBaseException {
+        ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
+        ZipSink zs = new ZipSink(byteOutputStream);
+
+        AtlasEntity entity = new AtlasEntity();
+        entity.setGuid(String.format(knownEntityGuidFormat, 0));
+
+        zs.add(entity);
+        assertTrue(zs.hasEntity(String.format(knownEntityGuidFormat, 0)));
+
+        zs.close();
+    }
+
+    @Test
+    public void recordsEntityWithExtInfoEntries() throws AtlasBaseException {
+        final int max_entries = 3;
+        ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
+        ZipSink zs = new ZipSink(byteOutputStream);
+
+        AtlasEntity entity = new AtlasEntity();
+        entity.setGuid(String.format(knownEntityGuidFormat, 0));
+
+        AtlasEntity.AtlasEntityWithExtInfo entityWithExtInfo = new AtlasEntity.AtlasEntityWithExtInfo(entity);
+        addReferredEntities(entityWithExtInfo, max_entries);
+
+        zs.add(entityWithExtInfo);
+        for (int i = 0; i <= max_entries; i++) {
+            String g = String.format(knownEntityGuidFormat, i);
+            assertTrue(zs.hasEntity(g));
+        }
+
+        zs.close();
+    }
+
+    private void addReferredEntities(AtlasEntity.AtlasEntityWithExtInfo entityWithExtInfo, int maxEntries) {
+
+        for (int i = 1; i <= maxEntries; i++) {
+            AtlasEntity entity1 = new AtlasEntity();
+            entity1.setGuid(String.format(knownEntityGuidFormat, i));
+            entityWithExtInfo.addReferredEntity(entity1);
+        }
+    }
+
+    @Test
+    public void recordsDoesNotRecordEntityEntries() throws AtlasBaseException {
+        initZipSinkWithExportOrder();
+
+        assertNotNull(zipSink);
+        assertFalse(zipSink.hasEntity(ZipExportFileNames.ATLAS_EXPORT_ORDER_NAME.toString()));
+    }
+
+    private void useZipSinkToCreateEntries(ByteArrayOutputStream byteOutputStream) throws AtlasBaseException {
+        ZipSink zs = new ZipSink(byteOutputStream);
+        zs.setExportOrder(defaultExportOrder);
+        zs.setResult(getDefaultExportResult());
+        zs.close();
+    }
+
+    private boolean compareJsonWithObject(String s, AtlasExportResult defaultExportResult) {
+        String json = AtlasType.toJson(defaultExportResult);
+        return json.equals(s);
+    }
+}
diff --git a/repository/src/test/java/org/apache/atlas/repository/impexp/ZipSourceTest.java b/repository/src/test/java/org/apache/atlas/repository/impexp/ZipSourceTest.java
new file mode 100644
index 0000000..1c1c68f
--- /dev/null
+++ b/repository/src/test/java/org/apache/atlas/repository/impexp/ZipSourceTest.java
@@ -0,0 +1,189 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.repository.impexp;
+
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.instance.AtlasEntity;
+import org.apache.atlas.model.typedef.AtlasTypesDef;
+import org.testng.Assert;
+import org.testng.ITestContext;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.List;
+
+import static org.apache.atlas.repository.impexp.ZipFileResourceTestUtils.getZipSource;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.AssertJUnit.assertTrue;
+
+public class ZipSourceTest {
+    @DataProvider(name = "zipFileStocks")
+    public static Object[][] getDataFromZipFile() throws IOException {
+        FileInputStream fs = ZipFileResourceTestUtils.getFileInputStream("stocks.zip");
+
+        return new Object[][] {{ new ZipSource(fs) }};
+    }
+
+    @DataProvider(name = "zipFileStocksFloat")
+    public static Object[][] getDataFromZipFileWithLongFloats() throws IOException {
+        FileInputStream fs = ZipFileResourceTestUtils.getFileInputStream("stocks-float.zip");
+
+        return new Object[][] {{ new ZipSource(fs) }};
+    }
+
+    @DataProvider(name = "sales")
+    public static Object[][] getDataFromQuickStart_v1_Sales(ITestContext context) throws IOException {
+        return getZipSource("sales-v1-full.zip");
+    }
+
+    @Test
+    public void improperInit_ReturnsNullCreationOrder() throws IOException, AtlasBaseException {
+        byte bytes[] = new byte[10];
+        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+        ZipSource zs = new ZipSource(bais);
+        List<String> s = zs.getCreationOrder();
+        Assert.assertNull(s);
+    }
+
+    @Test(dataProvider = "zipFileStocks")
+    public void examineContents_BehavesAsExpected(ZipSource zipSource) throws IOException, AtlasBaseException {
+        List<String> creationOrder = zipSource.getCreationOrder();
+
+        assertNotNull(creationOrder);
+        assertEquals(creationOrder.size(), 4);
+
+        AtlasTypesDef typesDef = zipSource.getTypesDef();
+        assertNotNull(typesDef);
+        assertEquals(typesDef.getEntityDefs().size(), 6);
+
+        useCreationOrderToFetchEntitiesWithExtInfo(zipSource, creationOrder);
+        useCreationOrderToFetchEntities(zipSource, creationOrder);
+        attemptToFetchNonExistentGuid_ReturnsNull(zipSource, "non-existent-guid");
+        verifyGuidRemovalOnImportComplete(zipSource, creationOrder.get(0));
+    }
+
+    private void useCreationOrderToFetchEntities(ZipSource zipSource, List<String> creationOrder) {
+        for (String guid : creationOrder) {
+            AtlasEntity e = zipSource.getByGuid(guid);
+            assertNotNull(e);
+        }
+    }
+
+    private void verifyGuidRemovalOnImportComplete(ZipSource zipSource, String guid) {
+        AtlasEntity e = zipSource.getByGuid(guid);
+        assertNotNull(e);
+
+        zipSource.onImportComplete(guid);
+
+        e = zipSource.getByGuid(guid);
+        Assert.assertNull(e);
+    }
+
+    private void attemptToFetchNonExistentGuid_ReturnsNull(ZipSource zipSource, String guid) {
+        AtlasEntity e = zipSource.getByGuid(guid);
+        Assert.assertNull(e);
+    }
+
+    private void useCreationOrderToFetchEntitiesWithExtInfo(ZipSource zipSource, List<String> creationOrder) throws AtlasBaseException {
+        for (String guid : creationOrder) {
+            AtlasEntity.AtlasEntityExtInfo e = zipSource.getEntityWithExtInfo(guid);
+            assertNotNull(e);
+        }
+    }
+
+    @Test(dataProvider = "zipFileStocks")
+    public void iteratorBehavor_WorksAsExpected(ZipSource zipSource) throws IOException, AtlasBaseException {
+        Assert.assertTrue(zipSource.hasNext());
+
+        List<String> creationOrder = zipSource.getCreationOrder();
+        for (int i = 0; i < creationOrder.size(); i++) {
+            AtlasEntity e = zipSource.next();
+
+            assertNotNull(e);
+            assertEquals(e.getGuid(), creationOrder.get(i));
+        }
+
+        assertFalse(zipSource.hasNext());
+    }
+
+    @Test(dataProvider = "sales")
+    public void iteratorSetPositionBehavor(ZipSource zipSource) throws IOException, AtlasBaseException {
+        Assert.assertTrue(zipSource.hasNext());
+
+        List<String> creationOrder = zipSource.getCreationOrder();
+        int moveToPosition_2 = 2;
+        zipSource.setPosition(moveToPosition_2);
+
+        assertEquals(zipSource.getPosition(), moveToPosition_2);
+        assertTrue(zipSource.getPosition() < creationOrder.size());
+
+        assertTrue(zipSource.hasNext());
+        for (int i = 1; i < 4; i++) {
+            zipSource.next();
+            assertEquals(zipSource.getPosition(), moveToPosition_2 + i);
+        }
+
+        assertTrue(zipSource.hasNext());
+    }
+
+    @Test(dataProvider = "zipFileStocksFloat")
+    public void attemptToSerializeLongFloats(ZipSource zipSource) throws IOException, AtlasBaseException {
+        Assert.assertTrue(zipSource.hasNext());
+        assertTrue(zipSource.hasNext());
+        assertTrue(zipSource.hasNext());
+
+        AtlasEntity.AtlasEntityWithExtInfo e = zipSource.getNextEntityWithExtInfo();
+        assertNotNull(e);
+        assertTrue(e.getEntity().getClassifications().size() > 0);
+        assertNotNull(e.getEntity().getClassifications().get(0).getAttribute("fv"));
+        assertEquals(e.getEntity().getClassifications().get(0).getAttribute("fv").toString(), "3.4028235E+38");
+
+        assertTrue(zipSource.hasNext());
+    }
+
+    @Test(dataProvider = "zipFileStocks")
+    public void applyTransformation(ZipSource zipSource) throws IOException, AtlasBaseException {
+        ImportTransforms transforms = getTransformForHiveDB();
+        zipSource.setImportTransform(transforms);
+
+        Assert.assertTrue(zipSource.hasNext());
+        List<String> creationOrder = zipSource.getCreationOrder();
+        for (int i = 0; i < creationOrder.size(); i++) {
+            AtlasEntity e = zipSource.next();
+            if(e.getTypeName().equals("hive_db")) {
+                Object o = e.getAttribute("qualifiedName");
+                String s = (String) o;
+
+                assertNotNull(e);
+                assertTrue(s.contains("@cl2"));
+                break;
+            }
+        }
+    }
+
+    private ImportTransforms getTransformForHiveDB() {
+        ImportTransforms tr = ImportTransforms.fromJson("{ \"hive_db\": { \"qualifiedName\": [ \"replace:@cl1:@cl2\" ] } }");
+
+        return tr;
+    }
+}
diff --git a/repository/src/test/java/org/apache/atlas/repository/store/graph/AtlasTypeDefGraphStoreTest.java b/repository/src/test/java/org/apache/atlas/repository/store/graph/AtlasTypeDefGraphStoreTest.java
new file mode 100644
index 0000000..9088470
--- /dev/null
+++ b/repository/src/test/java/org/apache/atlas/repository/store/graph/AtlasTypeDefGraphStoreTest.java
@@ -0,0 +1,644 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.repository.store.graph;
+
+import com.google.inject.Inject;
+import org.apache.atlas.RequestContextV1;
+import org.apache.atlas.TestModules;
+import org.apache.atlas.TestUtilsV2;
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.SearchFilter;
+import org.apache.atlas.model.typedef.*;
+import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
+import org.apache.atlas.store.AtlasTypeDefStore;
+import org.apache.atlas.type.AtlasType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Arrays;
+import java.util.Date;
+
+import static org.testng.Assert.*;
+
+@Guice(modules = TestModules.TestOnlyModule.class)
+public class AtlasTypeDefGraphStoreTest {
+    private static final Logger LOG = LoggerFactory.getLogger(AtlasTypeDefGraphStoreTest.class);
+
+    @Inject
+    private
+    AtlasTypeDefStore typeDefStore;
+
+    @BeforeTest
+    public void setupTest() {
+        RequestContextV1.clear();
+        RequestContextV1.get().setUser(TestUtilsV2.TEST_USER);
+    }
+
+    @Test
+    public void testGet() {
+        try {
+            AtlasTypesDef typesDef = typeDefStore.searchTypesDef(new SearchFilter());
+            assertNotNull(typesDef.getEnumDefs());
+            assertEquals(typesDef.getStructDefs().size(), 0);
+            assertNotNull(typesDef.getStructDefs());
+            assertEquals(typesDef.getClassificationDefs().size(), 0);
+            assertNotNull(typesDef.getClassificationDefs());
+            assertEquals(typesDef.getEntityDefs().size(), 0);
+            assertNotNull(typesDef.getEntityDefs());
+        } catch (AtlasBaseException e) {
+            fail("Search of types shouldn't have failed");
+        }
+    }
+
+    @Test(dataProvider = "invalidGetProvider", dependsOnMethods = "testGet")
+    public void testInvalidGet(String name, String guid){
+        try {
+            assertNull(typeDefStore.getEnumDefByName(name));
+            fail("Exception expected for invalid name");
+        } catch (AtlasBaseException e) {
+        }
+
+        try {
+            assertNull(typeDefStore.getEnumDefByGuid(guid));
+            fail("Exception expected for invalid guid");
+        } catch (AtlasBaseException e) {
+        }
+
+        try {
+            assertNull(typeDefStore.getStructDefByName(name));
+            fail("Exception expected for invalid name");
+        } catch (AtlasBaseException e) {
+        }
+
+        try {
+            assertNull(typeDefStore.getStructDefByGuid(guid));
+            fail("Exception expected for invalid guid");
+        } catch (AtlasBaseException e) {
+        }
+
+        try {
+            assertNull(typeDefStore.getClassificationDefByName(name));
+            fail("Exception expected for invalid name");
+        } catch (AtlasBaseException e) {
+        }
+
+        try {
+            assertNull(typeDefStore.getClassificationDefByGuid(guid));
+            fail("Exception expected for invalid guid");
+        } catch (AtlasBaseException e) {
+        }
+
+        try {
+            assertNull(typeDefStore.getEntityDefByName(name));
+            fail("Exception expected for invalid name");
+        } catch (AtlasBaseException e) {
+        }
+
+        try {
+            assertNull(typeDefStore.getEntityDefByGuid(guid));
+            fail("Exception expected for invalid guid");
+        } catch (AtlasBaseException e) {
+        }
+    }
+
+    @DataProvider
+    public Object[][] invalidGetProvider(){
+        return new Object[][] {
+                {"name1", "guid1"},
+                {"", ""},
+                {null, null}
+        };
+    }
+
+    @DataProvider
+    public Object[][] validCreateDeptTypes(){
+        return new Object[][] {
+                {TestUtilsV2.defineDeptEmployeeTypes()}
+        };
+    }
+
+    @DataProvider
+    public Object[][] validUpdateDeptTypes(){
+        AtlasTypesDef typesDef = TestUtilsV2.defineValidUpdatedDeptEmployeeTypes();
+        return new Object[][] {
+                {typesDef}
+        };
+    }
+
+    @DataProvider
+    public Object[][] allCreatedTypes(){
+        // Capture all the types that are getting created or updated here.
+        AtlasTypesDef updatedTypeDefs = TestUtilsV2.defineValidUpdatedDeptEmployeeTypes();
+        AtlasTypesDef allTypeDefs = new AtlasTypesDef();
+        allTypeDefs.getEnumDefs().addAll(updatedTypeDefs.getEnumDefs());
+        allTypeDefs.getStructDefs().addAll(updatedTypeDefs.getStructDefs());
+        allTypeDefs.getClassificationDefs().addAll(updatedTypeDefs.getClassificationDefs());
+        allTypeDefs.getEntityDefs().addAll(updatedTypeDefs.getEntityDefs());
+        allTypeDefs.getEntityDefs().addAll(TestUtilsV2.getEntityWithValidSuperType());
+        return new Object[][] {{allTypeDefs}};
+    }
+
+    @DataProvider
+    public Object[][] invalidCreateTypes(){
+        // TODO: Create invalid type in TestUtilsV2
+        return new Object[][] {
+        };
+    }
+
+    @DataProvider
+    public Object[][] invalidUpdateTypes(){
+        return new Object[][] {
+                {TestUtilsV2.defineInvalidUpdatedDeptEmployeeTypes()}
+        };
+    }
+
+    @Test(dependsOnMethods = {"testGet"}, dataProvider = "validCreateDeptTypes")
+    public void testCreateDept(AtlasTypesDef atlasTypesDef) {
+        AtlasTypesDef existingTypesDef = null;
+        try {
+            existingTypesDef = typeDefStore.searchTypesDef(new SearchFilter());
+        } catch (AtlasBaseException e) {
+            // ignore
+        }
+
+        assertNotEquals(atlasTypesDef, existingTypesDef, "Types to be created already exist in the system");
+        AtlasTypesDef createdTypesDef = null;
+        try {
+            createdTypesDef = typeDefStore.createTypesDef(atlasTypesDef);
+            assertNotNull(createdTypesDef);
+            assertTrue(createdTypesDef.getEnumDefs().containsAll(atlasTypesDef.getEnumDefs()), "EnumDefs create failed");
+            assertTrue(createdTypesDef.getClassificationDefs().containsAll(atlasTypesDef.getClassificationDefs()), "ClassificationDef create failed");
+            assertTrue(createdTypesDef.getStructDefs().containsAll(atlasTypesDef.getStructDefs()), "StructDef creation failed");
+            Assert.assertEquals(createdTypesDef.getEntityDefs(), atlasTypesDef.getEntityDefs());
+
+        } catch (AtlasBaseException e) {
+            fail("Creation of Types should've been a success", e);
+        }
+    }
+
+    @Test(dependsOnMethods = {"testCreateDept"}, dataProvider = "validUpdateDeptTypes")
+    public void testUpdate(AtlasTypesDef atlasTypesDef){
+        try {
+            AtlasTypesDef updatedTypesDef = typeDefStore.updateTypesDef(atlasTypesDef);
+            assertNotNull(updatedTypesDef);
+
+            assertEquals(updatedTypesDef.getEnumDefs().size(), atlasTypesDef.getEnumDefs().size(), "EnumDefs update failed");
+            assertEquals(updatedTypesDef.getClassificationDefs().size(), atlasTypesDef.getClassificationDefs().size(), "ClassificationDef update failed");
+            assertEquals(updatedTypesDef.getStructDefs().size(), atlasTypesDef.getStructDefs().size(), "StructDef update failed");
+            assertEquals(updatedTypesDef.getEntityDefs().size(), atlasTypesDef.getEntityDefs().size(), "EntityDef update failed");
+
+            // Try another update round by name and GUID
+            for (AtlasEnumDef enumDef : updatedTypesDef.getEnumDefs()) {
+                AtlasEnumDef updated = typeDefStore.updateEnumDefByGuid(enumDef.getGuid(), enumDef);
+                assertNotNull(updated);
+            }
+            for (AtlasEnumDef enumDef : atlasTypesDef.getEnumDefs()) {
+                AtlasEnumDef updated = typeDefStore.updateEnumDefByName(enumDef.getName(), enumDef);
+                assertNotNull(updated);
+            }
+
+            // Try another update round by name and GUID
+            for (AtlasClassificationDef classificationDef : updatedTypesDef.getClassificationDefs()) {
+                AtlasClassificationDef updated = typeDefStore.updateClassificationDefByGuid(classificationDef.getGuid(), classificationDef);
+                assertNotNull(updated);
+            }
+            for (AtlasClassificationDef classificationDef : atlasTypesDef.getClassificationDefs()) {
+                AtlasClassificationDef updated = typeDefStore.updateClassificationDefByName(classificationDef.getName(), classificationDef);
+                assertNotNull(updated);
+            }
+
+            // Try another update round by name and GUID
+            for (AtlasStructDef structDef : updatedTypesDef.getStructDefs()) {
+                AtlasStructDef updated = typeDefStore.updateStructDefByGuid(structDef.getGuid(), structDef);
+                assertNotNull(updated);
+            }
+            for (AtlasStructDef structDef : atlasTypesDef.getStructDefs()) {
+                AtlasStructDef updated = typeDefStore.updateStructDefByName(structDef.getName(), structDef);
+                assertNotNull(updated);
+            }
+
+            // Try another update round by name and GUID
+            for (AtlasEntityDef entityDef : updatedTypesDef.getEntityDefs()) {
+                AtlasEntityDef updated = typeDefStore.updateEntityDefByGuid(entityDef.getGuid(), entityDef);
+                assertNotNull(updated);
+            }
+            for (AtlasEntityDef entityDef : atlasTypesDef.getEntityDefs()) {
+                AtlasEntityDef updated = typeDefStore.updateEntityDefByName(entityDef.getName(), entityDef);
+                assertNotNull(updated);
+            }
+
+        } catch (AtlasBaseException e) {
+            fail("TypeDef updates should've succeeded");
+        }
+    }
+
+    @Test(enabled = false, dependsOnMethods = {"testCreateDept"})
+    public void testUpdateWithMandatoryFields(){
+        AtlasTypesDef atlasTypesDef = TestUtilsV2.defineInvalidUpdatedDeptEmployeeTypes();
+        List<AtlasEnumDef> enumDefsToUpdate = atlasTypesDef.getEnumDefs();
+        List<AtlasClassificationDef> classificationDefsToUpdate = atlasTypesDef.getClassificationDefs();
+        List<AtlasStructDef> structDefsToUpdate = atlasTypesDef.getStructDefs();
+        List<AtlasEntityDef> entityDefsToUpdate = atlasTypesDef.getEntityDefs();
+
+        AtlasTypesDef onlyEnums = new AtlasTypesDef(enumDefsToUpdate,
+                Collections.EMPTY_LIST, Collections.EMPTY_LIST, Collections.EMPTY_LIST);
+
+        AtlasTypesDef onlyStructs = new AtlasTypesDef(Collections.EMPTY_LIST,
+                structDefsToUpdate, Collections.EMPTY_LIST, Collections.EMPTY_LIST);
+
+        AtlasTypesDef onlyClassification = new AtlasTypesDef(Collections.EMPTY_LIST,
+                Collections.EMPTY_LIST, classificationDefsToUpdate, Collections.EMPTY_LIST);
+
+        AtlasTypesDef onlyEntities = new AtlasTypesDef(Collections.EMPTY_LIST,
+                Collections.EMPTY_LIST, Collections.EMPTY_LIST, entityDefsToUpdate);
+
+        try {
+            AtlasTypesDef updated = typeDefStore.updateTypesDef(onlyEnums);
+            assertNotNull(updated);
+        } catch (AtlasBaseException ignored) {}
+
+        try {
+            AtlasTypesDef updated = typeDefStore.updateTypesDef(onlyClassification);
+            assertNotNull(updated);
+            assertEquals(updated.getClassificationDefs().size(), 0, "Updates should've failed");
+        } catch (AtlasBaseException ignored) {}
+
+        try {
+            AtlasTypesDef updated = typeDefStore.updateTypesDef(onlyStructs);
+            assertNotNull(updated);
+            assertEquals(updated.getStructDefs().size(), 0, "Updates should've failed");
+        } catch (AtlasBaseException ignored) {}
+
+        try {
+            AtlasTypesDef updated = typeDefStore.updateTypesDef(onlyEntities);
+            assertNotNull(updated);
+            assertEquals(updated.getEntityDefs().size(), 0, "Updates should've failed");
+        } catch (AtlasBaseException ignored) {}
+    }
+
+    // This should run after all the update calls
+    @Test(dependsOnMethods = {"testUpdate"}, dataProvider = "allCreatedTypes")
+    public void testDelete(AtlasTypesDef atlasTypesDef){
+        try {
+            typeDefStore.deleteTypesDef(atlasTypesDef);
+        } catch (AtlasBaseException e) {
+            fail("Deletion should've succeeded");
+        }
+    }
+
+    @Test(dependsOnMethods = "testGet")
+    public void testCreateWithValidAttributes(){
+        AtlasTypesDef hiveTypes = TestUtilsV2.defineHiveTypes();
+        try {
+            AtlasTypesDef createdTypes = typeDefStore.createTypesDef(hiveTypes);
+            assertEquals(hiveTypes.getEnumDefs(), createdTypes.getEnumDefs(), "Data integrity issue while persisting");
+            assertEquals(hiveTypes.getStructDefs(), createdTypes.getStructDefs(), "Data integrity issue while persisting");
+            assertEquals(hiveTypes.getClassificationDefs(), createdTypes.getClassificationDefs(), "Data integrity issue while persisting");
+            assertEquals(hiveTypes.getEntityDefs(), createdTypes.getEntityDefs(), "Data integrity issue while persisting");
+        } catch (AtlasBaseException e) {
+            fail("Hive Type creation should've succeeded");
+        }
+    }
+
+    @Test(enabled = false)
+    public void testCreateWithInvalidAttributes(){
+    }
+
+    @Test(dependsOnMethods = "testGet")
+    public void testCreateWithValidSuperTypes(){
+        // Test Classification with supertype
+        List<AtlasClassificationDef> classificationDefs = TestUtilsV2.getClassificationWithValidSuperType();
+
+        AtlasTypesDef toCreate = new AtlasTypesDef(Collections.<AtlasEnumDef>emptyList(),
+                Collections.<AtlasStructDef>emptyList(),
+                classificationDefs,
+                Collections.<AtlasEntityDef>emptyList());
+        try {
+            AtlasTypesDef created = typeDefStore.createTypesDef(toCreate);
+            assertEquals(created.getClassificationDefs(), toCreate.getClassificationDefs(),
+                    "Classification creation with valid supertype should've succeeded");
+        } catch (AtlasBaseException e) {
+            fail("Classification creation with valid supertype should've succeeded");
+        }
+
+        // Test Entity with supertype
+        List<AtlasEntityDef> entityDefs = TestUtilsV2.getEntityWithValidSuperType();
+        toCreate = new AtlasTypesDef(Collections.<AtlasEnumDef>emptyList(),
+                Collections.<AtlasStructDef>emptyList(),
+                Collections.<AtlasClassificationDef>emptyList(),
+                entityDefs);
+        try {
+            AtlasTypesDef created = typeDefStore.createTypesDef(toCreate);
+            assertEquals(created.getEntityDefs(), toCreate.getEntityDefs(),
+                    "Entity creation with valid supertype should've succeeded");
+        } catch (AtlasBaseException e) {
+            fail("Entity creation with valid supertype should've succeeded");
+        }
+    }
+
+    @Test(dependsOnMethods = "testGet")
+    public void testCreateWithInvalidSuperTypes(){
+        AtlasTypesDef typesDef;
+
+        // Test Classification with supertype
+        AtlasClassificationDef classificationDef = TestUtilsV2.getClassificationWithInvalidSuperType();
+        typesDef = new AtlasTypesDef();
+        typesDef.getClassificationDefs().add(classificationDef);
+        try {
+            AtlasTypesDef created = typeDefStore.createTypesDef(typesDef);
+            fail("Classification creation with invalid supertype should've failed");
+        } catch (AtlasBaseException e) {
+            typesDef = null;
+        }
+
+        // Test Entity with supertype
+        AtlasEntityDef entityDef = TestUtilsV2.getEntityWithInvalidSuperType();
+        typesDef = new AtlasTypesDef();
+        typesDef.getEntityDefs().add(entityDef);
+        try {
+            AtlasTypesDef created = typeDefStore.createTypesDef(typesDef);
+            fail("Entity creation with invalid supertype should've failed");
+        } catch (AtlasBaseException e) {}
+
+    }
+
+    @Test(dependsOnMethods = "testGet")
+    public void testCreateClassificationDefWithValidEntityType(){
+        final String entityTypeName ="testCreateClassificationDefWithValidEntityTypeEntity1";
+        final String classificationTypeName ="testCreateClassificationDefWithValidEntityTypeClassification1";
+
+        List<AtlasEntityDef> entityDefs = TestUtilsV2.getEntityWithName(entityTypeName);
+
+        // Test Classification with entitytype
+        List<AtlasClassificationDef> classificationDefs = TestUtilsV2.getClassificationWithName(classificationTypeName);
+
+        Set<String> entityTypeNames =  new HashSet<String>();
+        entityTypeNames.add(entityTypeName);
+        classificationDefs.get(0).setEntityTypes(entityTypeNames);
+        AtlasTypesDef toCreate = new AtlasTypesDef(Collections.<AtlasEnumDef>emptyList(),
+                Collections.<AtlasStructDef>emptyList(),
+                classificationDefs,
+                entityDefs);
+        try {
+            AtlasTypesDef created = typeDefStore.createTypesDef(toCreate);
+            assertEquals(created.getClassificationDefs(), toCreate.getClassificationDefs(),
+                    "Classification creation with valid entitytype should've succeeded");
+        } catch (AtlasBaseException e) {
+            fail("Classification creation with valid entitytype should've succeeded. Failed with " + e.getMessage());
+        }
+    }
+
+    @Test(dependsOnMethods = "testGet")
+    public void testCreateWithInvalidEntityType(){
+        final String classificationTypeName ="testCreateClassificationDefWithInvalidEntityTypeClassification1";
+        // Test Classification with entitytype
+        List<AtlasClassificationDef> classificationDefs = TestUtilsV2.getClassificationWithName(classificationTypeName);
+
+        Set<String> entityTypeNames =  new HashSet<String>();
+        entityTypeNames.add("cccc");
+        classificationDefs.get(0).setEntityTypes(entityTypeNames);
+        AtlasTypesDef toCreate = new AtlasTypesDef(Collections.<AtlasEnumDef>emptyList(),
+                Collections.<AtlasStructDef>emptyList(),
+                classificationDefs,
+                Collections.<AtlasEntityDef>emptyList());
+        try {
+            AtlasTypesDef created = typeDefStore.createTypesDef(toCreate);
+            fail("Classification creation with invalid entitytype should've failed");
+        } catch (AtlasBaseException e) {
+
+        }
+    }
+
+    /**
+     * test that specifying an entitytype in a child classificationDef when then parent has unrestricted entityTypes fails.
+     */
+    @Test(dependsOnMethods = "testGet")
+    public void testCreateWithInvalidEntityType2(){
+        final String classificationTypeName1 ="testCreateClassificationDefWithInvalidEntityType2Classification1";
+        final String classificationTypeName2 ="testCreateClassificationDefWithInvalidEntityType2Classification2";
+        final String entityTypeName1 ="testCreateClassificationDefWithInvalidEntityType2Entity1";
+
+        // Test Classification with entitytype
+        AtlasClassificationDef classificationDef1 = TestUtilsV2.getSingleClassificationWithName(classificationTypeName1);
+        AtlasClassificationDef classificationDef2 = TestUtilsV2.getSingleClassificationWithName(classificationTypeName2);
+        List<AtlasEntityDef> entityDefs = TestUtilsV2.getEntityWithName(entityTypeName1);
+
+
+        Set<String> entityTypeNames =  new HashSet<String>();
+        entityTypeNames.add(entityTypeName1);
+
+        Set<String> superTypes =  new HashSet<String>();
+        superTypes.add(classificationTypeName1);
+
+        classificationDef2.setSuperTypes(superTypes);
+        classificationDef1.setEntityTypes(entityTypeNames);
+
+        TestUtilsV2.populateSystemAttributes(classificationDef1);
+        TestUtilsV2.populateSystemAttributes(classificationDef2);
+
+        List<AtlasClassificationDef>  classificationDefs = Arrays.asList(classificationDef1,classificationDef2);
+
+        AtlasTypesDef toCreate = new AtlasTypesDef(Collections.<AtlasEnumDef>emptyList(),
+                Collections.<AtlasStructDef>emptyList(),
+                classificationDefs,
+                Collections.<AtlasEntityDef>emptyList());
+        try {
+            AtlasTypesDef created = typeDefStore.createTypesDef(toCreate);
+            fail("Classification creation with invalid entitytype should've failed");
+        } catch (AtlasBaseException e) {
+
+        }
+    }
+
+    /**
+     * test that specifying an entitytype in a child classificationDef which is not in the parent fails
+     */
+    @Test(dependsOnMethods = "testGet")
+    public void testCreateWithInvalidEntityType3(){
+        final String classificationTypeName1 ="testCreateClassificationDefWithInvalidEntityType3Classification1";
+        final String classificationTypeName2 ="testCreateClassificationDefWithInvalidEntityType3Classification2";
+        final String entityTypeName1 ="testCreateClassificationDefWithInvalidEntityType3Entity1";
+        final String entityTypeName2 ="testCreateClassificationDefWithInvalidEntityType3Entity2";
+
+
+        // Test Classification with entitytype
+        AtlasClassificationDef classificationDef1 = TestUtilsV2.getSingleClassificationWithName(classificationTypeName1);
+        AtlasClassificationDef classificationDef2 = TestUtilsV2.getSingleClassificationWithName(classificationTypeName2);
+        AtlasEntityDef entityDef1 = TestUtilsV2.getSingleEntityWithName(entityTypeName1);
+        AtlasEntityDef entityDef2 = TestUtilsV2.getSingleEntityWithName(entityTypeName2);
+
+        Set<String> entityTypeNames1 =  new HashSet<String>();
+        entityTypeNames1.add(entityTypeName1);
+
+        Set<String> entityTypeNames2 =  new HashSet<String>();
+        entityTypeNames2.add(entityTypeName2);
+
+        Set<String> superTypes =  new HashSet<String>();
+        superTypes.add(classificationTypeName1);
+
+        classificationDef1.setEntityTypes(entityTypeNames1);
+
+
+        classificationDef2.setSuperTypes(superTypes);
+        classificationDef2.setEntityTypes(entityTypeNames2);
+
+        TestUtilsV2.populateSystemAttributes(classificationDef1);
+        TestUtilsV2.populateSystemAttributes(classificationDef2);
+        TestUtilsV2.populateSystemAttributes(entityDef1);
+        TestUtilsV2.populateSystemAttributes(entityDef2);
+
+        List<AtlasClassificationDef>  classificationDefs = Arrays.asList(classificationDef1,classificationDef2);
+        List<AtlasEntityDef>  entityDefs = Arrays.asList(entityDef1,entityDef2);
+
+        AtlasTypesDef toCreate = new AtlasTypesDef(Collections.<AtlasEnumDef>emptyList(),
+                Collections.<AtlasStructDef>emptyList(),
+                classificationDefs,
+                entityDefs);
+        try {
+            AtlasTypesDef created = typeDefStore.createTypesDef(toCreate);
+            fail("Classification creation with invalid entitytype should've failed");
+        } catch (AtlasBaseException e) {
+
+        }
+    }
+
+    @Test(dependsOnMethods = "testGet")
+    public void testSearchFunctionality() {
+        SearchFilter searchFilter = new SearchFilter();
+        searchFilter.setParam(SearchFilter.PARAM_SUPERTYPE, "Person");
+
+        try {
+            AtlasTypesDef typesDef = typeDefStore.searchTypesDef(searchFilter);
+            assertNotNull(typesDef);
+            assertNotNull(typesDef.getEntityDefs());
+            assertEquals(typesDef.getEntityDefs().size(), 3);
+        } catch (AtlasBaseException e) {
+            fail("Search should've succeeded", e);
+        }
+    }
+
+    @Test(dependsOnMethods = "testGet")
+    public void testTypeDeletionAndRecreate() {
+        AtlasClassificationDef aTag = new AtlasClassificationDef("testTag");
+        AtlasAttributeDef attributeDef = new AtlasAttributeDef("testAttribute", "string", true,
+                AtlasAttributeDef.Cardinality.SINGLE, 0, 1,
+                false, true,
+                Collections.<AtlasStructDef.AtlasConstraintDef>emptyList());
+        aTag.addAttribute(attributeDef);
+
+        AtlasTypesDef typesDef = new AtlasTypesDef();
+        typesDef.setClassificationDefs(Arrays.asList(aTag));
+
+        try {
+            typeDefStore.createTypesDef(typesDef);
+        } catch (AtlasBaseException e) {
+            fail("Tag creation should've succeeded");
+        }
+
+        try {
+            typeDefStore.deleteTypesDef(typesDef);
+        } catch (AtlasBaseException e) {
+            fail("Tag deletion should've succeeded");
+        }
+
+        aTag = new AtlasClassificationDef("testTag");
+        attributeDef = new AtlasAttributeDef("testAttribute", "int", true,
+                AtlasAttributeDef.Cardinality.SINGLE, 0, 1,
+                false, true,
+                Collections.<AtlasStructDef.AtlasConstraintDef>emptyList());
+        aTag.addAttribute(attributeDef);
+        typesDef.setClassificationDefs(Arrays.asList(aTag));
+
+        try {
+            typeDefStore.createTypesDef(typesDef);
+        } catch (AtlasBaseException e) {
+            fail("Tag re-creation should've succeeded");
+        }
+    }
+
+    @Test(dependsOnMethods = "testGet")
+    public void testTypeRegistryIsUpdatedAfterGraphStorage() throws AtlasBaseException {
+      String classificationDef = "{"
+          + "\"name\":\"test_classification_11\","
+          + "\"description\":\"\","
+          + "\"createdBy\":\"admin\","
+          + "\"superTypes\":[],"
+          + "\"attributeDefs\":[{"
+          + "\"name\":\"test_class_11\","
+          + "\"typeName\":\"string\","
+          + "\"isOptional\":true,"
+          + "\"isUnique\":true,"
+          + "\"isIndexable\":true,"
+          + "\"cardinality\":\"SINGLE\","
+          + "\"valuesMinCount\":0,"
+          + "\"valuesMaxCount\":1}]}";
+
+      String jsonStr = "{"
+          + "\"classificationDefs\":[" + classificationDef + "],"
+          + "\"entityDefs\":[],"
+          + "\"enumDefs\":[],"
+          + "\"structDefs\":[]}";
+
+      // create type from json string
+      AtlasTypesDef testTypesDefFromJson = AtlasType.fromJson(jsonStr, AtlasTypesDef.class);
+      AtlasTypesDef createdTypesDef = typeDefStore.createTypesDef(testTypesDefFromJson);
+      // check returned type
+      assertEquals("test_classification_11", createdTypesDef.getClassificationDefs().get(0).getName());
+      assertTrue(createdTypesDef.getClassificationDefs().get(0).getAttributeDefs().get(0).getIsIndexable());
+      // save guid
+      String guid = createdTypesDef.getClassificationDefs().get(0).getGuid();
+      Date createdTime = createdTypesDef.getClassificationDefs().get(0).getCreateTime();
+
+      // get created type and check again
+      AtlasClassificationDef getBackFromCache = typeDefStore.getClassificationDefByName("test_classification_11");
+      assertEquals("test_classification_11", getBackFromCache.getName());
+      assertTrue(getBackFromCache.getAttributeDefs().get(0).getIsIndexable());
+      assertEquals(guid, getBackFromCache.getGuid());
+      assertNotNull(getBackFromCache.getCreatedBy());
+      assertEquals(createdTime, getBackFromCache.getCreateTime());
+
+      // update type, change isIndexable, check the update result
+      testTypesDefFromJson = AtlasType.fromJson(jsonStr, AtlasTypesDef.class);
+      testTypesDefFromJson.getClassificationDefs().get(0).getAttributeDefs().get(0).setIsIndexable(false);
+      AtlasTypesDef updatedTypesDef = typeDefStore.updateTypesDef(testTypesDefFromJson);
+      assertEquals("test_classification_11", updatedTypesDef.getClassificationDefs().get(0).getName());
+      assertFalse(updatedTypesDef.getClassificationDefs().get(0).getAttributeDefs().get(0).getIsIndexable());
+      assertEquals(guid, updatedTypesDef.getClassificationDefs().get(0).getGuid());
+      assertEquals(createdTime, updatedTypesDef.getClassificationDefs().get(0).getCreateTime());
+
+      // get updated type (both by name and guid) and check again
+      getBackFromCache = typeDefStore.getClassificationDefByName("test_classification_11");
+      assertEquals("test_classification_11", getBackFromCache.getName());
+      assertFalse(getBackFromCache.getAttributeDefs().get(0).getIsIndexable());
+      assertEquals(guid, getBackFromCache.getGuid());
+      assertEquals(createdTime, getBackFromCache.getCreateTime());
+      getBackFromCache = typeDefStore.getClassificationDefByGuid(guid);
+      assertEquals("test_classification_11", getBackFromCache.getName());
+      assertFalse(getBackFromCache.getAttributeDefs().get(0).getIsIndexable());
+      assertEquals(guid, getBackFromCache.getGuid());
+      assertEquals(createdTime, getBackFromCache.getCreateTime());
+    }
+}
diff --git a/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityDefStoreV1Test.java b/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityDefStoreV1Test.java
new file mode 100644
index 0000000..1198283
--- /dev/null
+++ b/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityDefStoreV1Test.java
@@ -0,0 +1,73 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.repository.store.graph.v1;
+
+import com.google.inject.Inject;
+import org.apache.atlas.ApplicationProperties;
+import org.apache.atlas.AtlasErrorCode;
+import org.apache.atlas.AtlasException;
+import org.apache.atlas.TestModules;
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.typedef.AtlasEntityDef;
+import org.apache.atlas.repository.graph.AtlasGraphProvider;
+import org.apache.atlas.type.AtlasTypeUtil;
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+
+import java.util.Collections;
+
+/**
+ * Tests for AtlasEntityStoreV1
+ */
+@Guice(modules = TestModules.TestOnlyModule.class)
+public class AtlasEntityDefStoreV1Test {
+
+    @Inject
+    private
+    AtlasEntityDefStoreV1 entityDefStore;
+
+    @DataProvider
+    public Object[][] invalidAttributeNameWithReservedKeywords(){
+        AtlasEntityDef invalidAttrNameType =
+            AtlasTypeUtil.createClassTypeDef("Invalid_Attribute_Type", "description", Collections.emptySet(),
+                AtlasTypeUtil.createRequiredAttrDef("order", "string"),
+                AtlasTypeUtil.createRequiredAttrDef("limit", "string"));
+
+        return new Object[][] {{
+            invalidAttrNameType
+        }};
+    }
+
+    @Test(dataProvider = "invalidAttributeNameWithReservedKeywords")
+    public void testCreateTypeWithReservedKeywords(AtlasEntityDef atlasEntityDef) throws AtlasException {
+        try {
+            ApplicationProperties.get().setProperty(AtlasAbstractDefStoreV1.ALLOW_RESERVED_KEYWORDS, false);
+            entityDefStore.create(atlasEntityDef, null);
+        } catch (AtlasBaseException e) {
+            Assert.assertEquals(e.getAtlasErrorCode(), AtlasErrorCode.ATTRIBUTE_NAME_INVALID);
+        }
+    }
+
+    @AfterClass
+    public void clear(){
+        AtlasGraphProvider.cleanup();
+    }
+}
diff --git a/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1BulkImportPercentTest.java b/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1BulkImportPercentTest.java
new file mode 100644
index 0000000..73dfe37
--- /dev/null
+++ b/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1BulkImportPercentTest.java
@@ -0,0 +1,167 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.repository.store.graph.v1;
+
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.slf4j.Logger;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.mockito.Matchers.*;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+public class AtlasEntityStoreV1BulkImportPercentTest {
+
+    private final int MAX_PERCENT = 100;
+    private List<Integer> percentHolder;
+    private Logger log;
+
+    public void setupPercentHolder(int max) {
+        percentHolder = new ArrayList<>();
+    }
+
+    @BeforeClass
+    void mockLog() {
+        log = mock(Logger.class);
+
+        doAnswer(new Answer() {
+            @Override
+            public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
+                Object[] args = invocationOnMock.getArguments();
+                Integer d = (Integer) args[1];
+                percentHolder.add(d.intValue());
+                return null;
+            }
+        }).when(log).info(anyString(), anyFloat(), anyInt(), anyString());
+    }
+
+    @Test
+    public void percentTest_Equal4() throws Exception {
+        runWithSize(4);
+        assertEqualsForPercentHolder(25.0, 50.0, 75.0, 100.0);
+    }
+
+    @Test
+    public void percentTest_Equal10() throws Exception {
+        runWithSize(10);
+
+        assertEqualsForPercentHolder(10.0, 20.0, 30.0, 40.0, 50, 60, 70, 80, 90, 100);
+    }
+
+    private void assertEqualsForPercentHolder(double... expected) {
+        assertEquals(percentHolder.size(), expected.length);
+        Object actual[] = percentHolder.toArray();
+        for (int i = 0; i < expected.length; i++) {
+            assertTrue((int) Double.compare((int) actual[i], expected[i]) == 0);
+        }
+    }
+
+    @Test
+    public void bulkImportPercentageTestLessThan100() throws Exception {
+        int streamSize = 20;
+
+        runWithSize(streamSize);
+        assertEqualsForPercentHolder(5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100);
+    }
+
+    @Test
+    public void percentTest_Equal101() throws Exception {
+        int streamSize = 101;
+
+        double[] expected = fillPercentHolderWith100();
+
+        runWithSize(streamSize);
+        assertEqualsForPercentHolder(expected);
+    }
+
+    @Test
+    public void percentTest_Equal200() throws Exception {
+        int streamSize = 200;
+
+        double[] expected = fillPercentHolderWith100();
+
+        runWithSize(streamSize);
+        assertEqualsForPercentHolder(expected);
+    }
+
+    @Test
+    public void percentTest_Equal202() throws Exception {
+        int streamSize = 202;
+
+        double[] expected = fillPercentHolderWith100();
+
+        runWithSize(streamSize);
+        assertEqualsForPercentHolder(expected);
+    }
+
+    @Test
+    public void percentTest_Equal1001() throws Exception {
+        int streamSize = 1001;
+        double[] expected = fillPercentHolderWith100();
+
+        runWithSize(streamSize);
+        assertEqualsForPercentHolder(expected);
+    }
+
+    @Test
+    public void percentTest_Equal4323() throws Exception {
+        int streamSize = 4323;
+
+        double[] expected = fillPercentHolderWith100();
+        runWithSize(streamSize);
+        assertEqualsForPercentHolder(expected);
+    }
+
+    @Test
+    public void percentTest_Equal269() throws Exception {
+        int streamSize = 269;
+
+        double[] expected = fillPercentHolderWith100();
+        runWithSize(streamSize);
+        assertEqualsForPercentHolder(expected);
+    }
+
+    private void runWithSize(int streamSize) throws Exception {
+        float currentPercent = 0;
+        setupPercentHolder(streamSize);
+        for (int currentIndex = 0; currentIndex < streamSize; currentIndex++) {
+            currentPercent = invokeBulkImportProgress(currentIndex + 1, streamSize, currentPercent);
+        }
+    }
+
+    private float invokeBulkImportProgress(int currentIndex, int streamSize, float currentPercent) throws Exception {
+        return BulkImporterImpl.updateImportProgress(log, currentIndex, streamSize, currentPercent, "additional info");
+    }
+
+    private double[] fillPercentHolderWith100() {
+        double start = 1;
+        double expected[] = new double[MAX_PERCENT];
+        for (int i = 0; i < expected.length; i++) {
+            expected[i] = start;
+            start ++;
+        }
+        return expected;
+    }
+}
diff --git a/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1Test.java b/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1Test.java
new file mode 100644
index 0000000..fd1b6db
--- /dev/null
+++ b/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1Test.java
@@ -0,0 +1,1043 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.repository.store.graph.v1;
+
+import com.google.common.collect.ImmutableSet;
+import org.apache.atlas.AtlasErrorCode;
+import org.apache.atlas.AtlasException;
+import org.apache.atlas.TestModules;
+import org.apache.atlas.RequestContextV1;
+import org.apache.atlas.TestUtilsV2;
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.instance.AtlasClassification;
+import org.apache.atlas.model.instance.AtlasEntity;
+import org.apache.atlas.model.instance.AtlasEntity.AtlasEntitiesWithExtInfo;
+import org.apache.atlas.model.instance.AtlasEntity.AtlasEntityExtInfo;
+import org.apache.atlas.model.instance.AtlasEntity.AtlasEntityWithExtInfo;
+import org.apache.atlas.model.instance.AtlasEntityHeader;
+import org.apache.atlas.model.instance.AtlasObjectId;
+import org.apache.atlas.model.instance.AtlasStruct;
+import org.apache.atlas.model.instance.EntityMutationResponse;
+import org.apache.atlas.model.instance.EntityMutations;
+import org.apache.atlas.model.instance.EntityMutations.EntityOperation;
+import org.apache.atlas.model.typedef.AtlasClassificationDef;
+import org.apache.atlas.model.typedef.AtlasEntityDef;
+import org.apache.atlas.model.typedef.AtlasStructDef;
+import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
+import org.apache.atlas.model.typedef.AtlasTypesDef;
+import org.apache.atlas.repository.graph.AtlasGraphProvider;
+import org.apache.atlas.repository.graph.GraphBackedSearchIndexer;
+import org.apache.atlas.repository.store.bootstrap.AtlasTypeDefStoreInitializer;
+import org.apache.atlas.repository.store.graph.AtlasEntityStore;
+import org.apache.atlas.store.AtlasTypeDefStore;
+import org.apache.atlas.type.AtlasArrayType;
+import org.apache.atlas.type.AtlasMapType;
+import org.apache.atlas.type.AtlasStructType;
+import org.apache.atlas.type.AtlasType;
+import org.apache.atlas.type.AtlasTypeRegistry;
+import org.apache.atlas.type.AtlasTypeUtil;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+
+import javax.inject.Inject;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.apache.atlas.TestUtilsV2.COLUMNS_ATTR_NAME;
+import static org.apache.atlas.TestUtilsV2.COLUMN_TYPE;
+import static org.apache.atlas.TestUtilsV2.NAME;
+import static org.apache.atlas.TestUtilsV2.randomString;
+import static org.apache.atlas.TestUtilsV2.STORAGE_DESC_TYPE;
+import static org.apache.atlas.TestUtilsV2.TABLE_TYPE;
+import static org.mockito.Mockito.mock;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+@Guice(modules = TestModules.TestOnlyModule.class)
+public class AtlasEntityStoreV1Test {
+    private static final Logger LOG = LoggerFactory.getLogger(AtlasEntityStoreV1Test.class);
+
+    @Inject
+    AtlasTypeRegistry typeRegistry;
+
+    @Inject
+    AtlasTypeDefStore typeDefStore;
+
+    AtlasEntityStore entityStore;
+
+    @Inject
+    DeleteHandlerV1 deleteHandler;
+
+    private AtlasEntitiesWithExtInfo deptEntity;
+    private AtlasEntityWithExtInfo   dbEntity;
+    private AtlasEntityWithExtInfo   tblEntity;
+    private AtlasEntityWithExtInfo   primitiveEntity;
+
+    AtlasEntityChangeNotifier mockChangeNotifier = mock(AtlasEntityChangeNotifier.class);
+    @Inject
+    private EntityGraphMapper graphMapper;
+
+
+    @BeforeClass
+    public void setUp() throws Exception {
+        RequestContextV1.clear();
+        RequestContextV1.get().setUser(TestUtilsV2.TEST_USER);
+
+        new GraphBackedSearchIndexer(typeRegistry);
+
+        AtlasTypesDef[] testTypesDefs = new AtlasTypesDef[] { TestUtilsV2.defineDeptEmployeeTypes(),
+                                                              TestUtilsV2.defineHiveTypes()
+                                                            };
+
+        for (AtlasTypesDef typesDef : testTypesDefs) {
+            AtlasTypesDef typesToCreate = AtlasTypeDefStoreInitializer.getTypesToCreate(typesDef, typeRegistry);
+
+            if (!typesToCreate.isEmpty()) {
+                typeDefStore.createTypesDef(typesToCreate);
+            }
+        }
+
+        deptEntity = TestUtilsV2.createDeptEg2();
+        dbEntity   = TestUtilsV2.createDBEntityV2();
+        tblEntity  = TestUtilsV2.createTableEntityV2(dbEntity.getEntity());
+
+        AtlasTypesDef typesDef11 = new  AtlasTypesDef();
+        List primitiveEntityDef = new ArrayList<AtlasEntityDef>();
+        primitiveEntityDef.add(TestUtilsV2.createPrimitiveEntityDef());
+        typesDef11.setEntityDefs(primitiveEntityDef);
+        typeDefStore.createTypesDef( typesDef11 );
+
+        primitiveEntity = TestUtilsV2.createprimitiveEntityV2();
+    }
+
+    @AfterClass
+    public void clear() {
+        AtlasGraphProvider.cleanup();
+    }
+
+    @BeforeTest
+    public void init() throws Exception {
+        entityStore = new AtlasEntityStoreV1(deleteHandler, typeRegistry, mockChangeNotifier, graphMapper);
+        RequestContextV1.clear();
+        RequestContextV1.get().setUser(TestUtilsV2.TEST_USER);
+    }
+
+    @Test
+    public void testDefaultValueForPrimitiveTypes() throws Exception  {
+
+        init();
+
+        EntityMutationResponse response = entityStore.createOrUpdate(new AtlasEntityStream(primitiveEntity), false);
+        List<AtlasEntityHeader> entitiesCreatedResponse = response.getEntitiesByOperation(EntityOperation.CREATE);
+        final Map<EntityOperation, List<AtlasEntityHeader>> entitiesMutated = response.getMutatedEntities();
+        List<AtlasEntityHeader> entitiesCreatedwithdefault = entitiesMutated.get(EntityOperation.CREATE);
+
+        AtlasEntity entityCreated   = getEntityFromStore(entitiesCreatedResponse.get(0));
+
+
+        Map attributesMap = entityCreated.getAttributes();
+        String description = (String) attributesMap.get("description");
+        String check = (String) attributesMap.get("check");
+        String   sourceCode =  (String) attributesMap.get("sourcecode");
+        float   diskUsage =  (float) attributesMap.get("diskUsage");
+        boolean   isstoreUse =  (boolean) attributesMap.get("isstoreUse");
+        int cost = (int)attributesMap.get("Cost");
+
+
+        assertEquals(description,"test");
+        assertEquals(check,"check");
+
+        //defaultValue
+        assertEquals(diskUsage,70.5f);
+        assertEquals(isstoreUse,true);
+        assertEquals(sourceCode,"Hello World");
+        assertEquals(cost,30);
+    }
+
+
+    @Test
+    public void testCreate() throws Exception {
+        init();
+        EntityMutationResponse response = entityStore.createOrUpdate(new AtlasEntityStream(deptEntity), false);
+
+        validateMutationResponse(response, EntityOperation.CREATE, 5);
+        AtlasEntityHeader dept1 = response.getFirstCreatedEntityByTypeName(TestUtilsV2.DEPARTMENT_TYPE);
+        validateEntity(deptEntity, getEntityFromStore(dept1), deptEntity.getEntities().get(0));
+
+        final Map<EntityOperation, List<AtlasEntityHeader>> entitiesMutated = response.getMutatedEntities();
+        List<AtlasEntityHeader> entitiesCreated = entitiesMutated.get(EntityOperation.CREATE);
+
+        Assert.assertTrue(entitiesCreated.size() >= deptEntity.getEntities().size());
+
+        for (int i = 0; i < deptEntity.getEntities().size(); i++) {
+            AtlasEntity expected = deptEntity.getEntities().get(i);
+            AtlasEntity actual   = getEntityFromStore(entitiesCreated.get(i));
+
+            validateEntity(deptEntity, actual, expected);
+        }
+
+        //Create DB
+        init();
+        EntityMutationResponse dbCreationResponse = entityStore.createOrUpdate(new AtlasEntityStream(dbEntity), false);
+        validateMutationResponse(dbCreationResponse, EntityOperation.CREATE, 1);
+
+        AtlasEntityHeader db1 = dbCreationResponse.getFirstCreatedEntityByTypeName(TestUtilsV2.DATABASE_TYPE);
+        validateEntity(dbEntity, getEntityFromStore(db1));
+
+        //Create Table
+        //Update DB guid
+        AtlasObjectId dbObjectId = (AtlasObjectId) tblEntity.getEntity().getAttribute("database");
+        dbObjectId.setGuid(db1.getGuid());
+        tblEntity.addReferredEntity(dbEntity.getEntity());
+
+        init();
+        EntityMutationResponse tableCreationResponse = entityStore.createOrUpdate(new AtlasEntityStream(tblEntity), false);
+        validateMutationResponse(tableCreationResponse, EntityOperation.CREATE, 1);
+
+        AtlasEntityHeader tableEntity = tableCreationResponse.getFirstCreatedEntityByTypeName(TABLE_TYPE);
+        validateEntity(tblEntity, getEntityFromStore(tableEntity));
+    }
+
+    @Test(dependsOnMethods = "testCreate")
+    public void testArrayOfEntityUpdate() throws Exception {
+        AtlasEntity              tableEntity  = new AtlasEntity(tblEntity.getEntity());
+        List<AtlasObjectId>      columns      = new ArrayList<>();
+        AtlasEntitiesWithExtInfo entitiesInfo = new AtlasEntitiesWithExtInfo(tableEntity);
+
+
+        AtlasEntity col1 = TestUtilsV2.createColumnEntity(tableEntity);
+        col1.setAttribute(TestUtilsV2.NAME, "col1");
+
+        AtlasEntity col2 = TestUtilsV2.createColumnEntity(tableEntity);
+        col2.setAttribute(TestUtilsV2.NAME, "col2");
+
+        columns.add(AtlasTypeUtil.getAtlasObjectId(col1));
+        columns.add(AtlasTypeUtil.getAtlasObjectId(col2));
+
+        tableEntity.setAttribute(TestUtilsV2.COLUMNS_ATTR_NAME, columns);
+
+        entitiesInfo.addReferredEntity(dbEntity.getEntity());
+        entitiesInfo.addReferredEntity(col1);
+        entitiesInfo.addReferredEntity(col2);
+
+        init();
+        EntityMutationResponse response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false);
+
+        AtlasEntityHeader updatedTableHeader = response.getFirstUpdatedEntityByTypeName(tableEntity.getTypeName());
+        validateEntity(entitiesInfo, getEntityFromStore(updatedTableHeader));
+
+        //Complete update. Add  array elements - col3,col4
+        AtlasEntity col3 = TestUtilsV2.createColumnEntity(tableEntity);
+        col3.setAttribute(TestUtilsV2.NAME, "col3");
+
+        AtlasEntity col4 = TestUtilsV2.createColumnEntity(tableEntity);
+        col4.setAttribute(TestUtilsV2.NAME, "col4");
+
+        columns.add(AtlasTypeUtil.getAtlasObjectId(col3));
+        columns.add(AtlasTypeUtil.getAtlasObjectId(col4));
+        tableEntity.setAttribute(TestUtilsV2.COLUMNS_ATTR_NAME, columns);
+
+        entitiesInfo.addReferredEntity(col3);
+        entitiesInfo.addReferredEntity(col4);
+
+        init();
+        response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false);
+
+        updatedTableHeader = response.getFirstUpdatedEntityByTypeName(tableEntity.getTypeName());
+        validateEntity(entitiesInfo, getEntityFromStore(updatedTableHeader));
+
+        //Swap elements
+        columns.clear();
+        columns.add(AtlasTypeUtil.getAtlasObjectId(col4));
+        columns.add(AtlasTypeUtil.getAtlasObjectId(col3));
+        tableEntity.setAttribute(TestUtilsV2.COLUMNS_ATTR_NAME, columns);
+
+        init();
+        response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false);
+
+        updatedTableHeader = response.getFirstUpdatedEntityByTypeName(tableEntity.getTypeName());
+        AtlasEntity updatedEntity = getEntityFromStore(updatedTableHeader);
+        // deleted columns are also included in "columns" attribute
+        Assert.assertTrue(((List<AtlasObjectId>) updatedEntity.getAttribute(COLUMNS_ATTR_NAME)).size() >= 2);
+
+        assertEquals(response.getEntitiesByOperation(EntityMutations.EntityOperation.DELETE).size(), 2);  // col1, col2 are deleted
+
+        //Update array column to null
+        tableEntity.setAttribute(COLUMNS_ATTR_NAME, null);
+
+        init();
+        response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false);
+
+        updatedTableHeader = response.getFirstUpdatedEntityByTypeName(tableEntity.getTypeName());
+        validateEntity(entitiesInfo, getEntityFromStore(updatedTableHeader));
+        assertEquals(response.getEntitiesByOperation(EntityMutations.EntityOperation.DELETE).size(), 2);
+    }
+
+    @Test(dependsOnMethods = "testCreate")
+    public void testUpdateEntityWithMap() throws Exception {
+        AtlasEntity              tableEntity  = new AtlasEntity(tblEntity.getEntity());
+        AtlasEntitiesWithExtInfo entitiesInfo = new AtlasEntitiesWithExtInfo(tableEntity);
+        Map<String, AtlasStruct> partsMap     = new HashMap<>();
+        partsMap.put("part0", new AtlasStruct(TestUtilsV2.PARTITION_STRUCT_TYPE, TestUtilsV2.NAME, "test"));
+
+        tableEntity.setAttribute("partitionsMap", partsMap);
+
+        init();
+        EntityMutationResponse response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false);
+
+        AtlasEntityHeader tableDefinition1 = response.getFirstUpdatedEntityByTypeName(TABLE_TYPE);
+        AtlasEntity updatedTableDef1 = getEntityFromStore(tableDefinition1);
+        validateEntity(entitiesInfo, updatedTableDef1);
+                
+        Assert.assertTrue(partsMap.get("part0").equals(((Map<String, AtlasStruct>) updatedTableDef1.getAttribute("partitionsMap")).get("part0")));
+
+        //update map - add a map key
+        partsMap.put("part1", new AtlasStruct(TestUtilsV2.PARTITION_STRUCT_TYPE, TestUtilsV2.NAME, "test1"));
+        tableEntity.setAttribute("partitionsMap", partsMap);
+
+        init();
+        response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false);
+
+        AtlasEntityHeader tableDefinition2 = response.getFirstUpdatedEntityByTypeName(TABLE_TYPE);
+        AtlasEntity updatedTableDef2 = getEntityFromStore(tableDefinition2);
+        validateEntity(entitiesInfo, updatedTableDef2);
+
+        assertEquals(((Map<String, AtlasStruct>) updatedTableDef2.getAttribute("partitionsMap")).size(), 2);
+        Assert.assertTrue(partsMap.get("part1").equals(((Map<String, AtlasStruct>) updatedTableDef2.getAttribute("partitionsMap")).get("part1")));
+
+        //update map - remove a key and add another key
+        partsMap.remove("part0");
+        partsMap.put("part2", new AtlasStruct(TestUtilsV2.PARTITION_STRUCT_TYPE, TestUtilsV2.NAME, "test2"));
+        tableEntity.setAttribute("partitionsMap", partsMap);
+
+        init();
+        response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false);
+
+        AtlasEntityHeader tableDefinition3 = response.getFirstUpdatedEntityByTypeName(TABLE_TYPE);
+        AtlasEntity updatedTableDef3 = getEntityFromStore(tableDefinition3);
+        validateEntity(entitiesInfo, updatedTableDef3);
+
+        assertEquals(((Map<String, AtlasStruct>) updatedTableDef3.getAttribute("partitionsMap")).size(), 2);
+        Assert.assertNull(((Map<String, AtlasStruct>) updatedTableDef3.getAttribute("partitionsMap")).get("part0"));
+        Assert.assertTrue(partsMap.get("part2").equals(((Map<String, AtlasStruct>) updatedTableDef3.getAttribute("partitionsMap")).get("part2")));
+
+        //update struct value for existing map key
+        AtlasStruct partition2 = partsMap.get("part2");
+        partition2.setAttribute(TestUtilsV2.NAME, "test2Updated");
+
+        init();
+        response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false);
+
+        AtlasEntityHeader tableDefinition4 = response.getFirstUpdatedEntityByTypeName(TABLE_TYPE);
+        AtlasEntity updatedTableDef4 = getEntityFromStore(tableDefinition4);
+        validateEntity(entitiesInfo, updatedTableDef4);
+
+        assertEquals(((Map<String, AtlasStruct>) updatedTableDef4.getAttribute("partitionsMap")).size(), 2);
+        Assert.assertNull(((Map<String, AtlasStruct>) updatedTableDef4.getAttribute("partitionsMap")).get("part0"));
+        Assert.assertTrue(partsMap.get("part2").equals(((Map<String, AtlasStruct>) updatedTableDef4.getAttribute("partitionsMap")).get("part2")));
+
+        //Test map pointing to a class
+
+        AtlasEntity col0 = new AtlasEntity(TestUtilsV2.COLUMN_TYPE, TestUtilsV2.NAME, "test1");
+        col0.setAttribute("type", "string");
+        col0.setAttribute("table", AtlasTypeUtil.getAtlasObjectId(tableEntity));
+
+        AtlasEntityWithExtInfo col0WithExtendedInfo = new AtlasEntityWithExtInfo(col0);
+        col0WithExtendedInfo.addReferredEntity(tableEntity);
+        col0WithExtendedInfo.addReferredEntity(dbEntity.getEntity());
+
+        init();
+        entityStore.createOrUpdate(new AtlasEntityStream(col0WithExtendedInfo), false);
+
+        AtlasEntity col1 = new AtlasEntity(TestUtilsV2.COLUMN_TYPE, TestUtilsV2.NAME, "test2");
+        col1.setAttribute("type", "string");
+        col1.setAttribute("table", AtlasTypeUtil.getAtlasObjectId(tableEntity));
+
+        AtlasEntityWithExtInfo col1WithExtendedInfo = new AtlasEntityWithExtInfo(col1);
+        col1WithExtendedInfo.addReferredEntity(tableEntity);
+        col1WithExtendedInfo.addReferredEntity(dbEntity.getEntity());
+
+        init();
+        entityStore.createOrUpdate(new AtlasEntityStream(col1WithExtendedInfo), false);
+
+        Map<String, AtlasObjectId> columnsMap = new HashMap<String, AtlasObjectId>();
+        columnsMap.put("col0", AtlasTypeUtil.getAtlasObjectId(col0));
+        columnsMap.put("col1", AtlasTypeUtil.getAtlasObjectId(col1));
+
+        tableEntity.setAttribute(TestUtilsV2.COLUMNS_MAP, columnsMap);
+
+        entitiesInfo.addReferredEntity(col0);
+        entitiesInfo.addReferredEntity(col1);
+        init();
+        response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false);
+        AtlasEntityHeader tableDefinition5 = response.getFirstUpdatedEntityByTypeName(TABLE_TYPE);
+        validateEntity(entitiesInfo, getEntityFromStore(tableDefinition5));
+
+        //Swap elements
+        columnsMap.clear();
+        columnsMap.put("col0", AtlasTypeUtil.getAtlasObjectId(col1));
+        columnsMap.put("col1", AtlasTypeUtil.getAtlasObjectId(col0));
+
+        tableEntity.setAttribute(TestUtilsV2.COLUMNS_MAP, columnsMap);
+        init();
+        response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false);
+        AtlasEntityHeader tableDefinition6 = response.getFirstUpdatedEntityByTypeName(TABLE_TYPE);
+        validateEntity(entitiesInfo, getEntityFromStore(tableDefinition6));
+
+        Assert.assertEquals(entityStore.getById(col0.getGuid()).getEntity().getStatus(), AtlasEntity.Status.ACTIVE);
+        Assert.assertEquals(entityStore.getById(col1.getGuid()).getEntity().getStatus(), AtlasEntity.Status.ACTIVE);
+
+        //Drop the first key and change the class type as well to col0
+        columnsMap.clear();
+        columnsMap.put("col0", AtlasTypeUtil.getAtlasObjectId(col0));
+        init();
+
+        response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false);
+        AtlasEntityHeader tableDefinition7 = response.getFirstUpdatedEntityByTypeName(TABLE_TYPE);
+        validateEntity(entitiesInfo, getEntityFromStore(tableDefinition7));
+
+        //Clear state
+        tableEntity.setAttribute(TestUtilsV2.COLUMNS_MAP, null);
+        init();
+        response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false);
+        AtlasEntityHeader tableDefinition8 = response.getFirstUpdatedEntityByTypeName(TABLE_TYPE);
+        validateEntity(entitiesInfo, getEntityFromStore(tableDefinition8));
+    }
+
+    @Test(dependsOnMethods = "testCreate")
+    public void testMapOfPrimitivesUpdate() throws Exception {
+        AtlasEntity              tableEntity  = new AtlasEntity(tblEntity.getEntity());
+        AtlasEntitiesWithExtInfo entitiesInfo = new AtlasEntitiesWithExtInfo(tableEntity);
+
+        entitiesInfo.addReferredEntity(tableEntity);
+
+        //Add a new entry
+        Map<String, String> paramsMap = (Map<String, String>) tableEntity.getAttribute("parametersMap");
+        paramsMap.put("newParam", "value");
+        init();
+        EntityMutationResponse response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false);
+        validateMutationResponse(response, EntityMutations.EntityOperation.UPDATE, 1);
+        AtlasEntityHeader updatedTable = response.getFirstUpdatedEntityByTypeName(TABLE_TYPE);
+        validateEntity(entitiesInfo, getEntityFromStore(updatedTable));
+
+        //Remove an entry
+        paramsMap.remove("key1");
+        init();
+        response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false);
+        validateMutationResponse(response, EntityMutations.EntityOperation.UPDATE, 1);
+        updatedTable = response.getFirstUpdatedEntityByTypeName(TABLE_TYPE);
+        validateEntity(entitiesInfo, getEntityFromStore(updatedTable));
+    }
+
+    @Test(dependsOnMethods = "testCreate")
+    public void testArrayOfStructs() throws Exception {
+        //Modify array of structs
+        AtlasEntity              tableEntity  = new AtlasEntity(tblEntity.getEntity());
+        AtlasEntitiesWithExtInfo entitiesInfo = new AtlasEntitiesWithExtInfo(tableEntity);
+
+        List<AtlasStruct> partitions = new ArrayList<AtlasStruct>(){{
+            add(new AtlasStruct(TestUtilsV2.PARTITION_STRUCT_TYPE, TestUtilsV2.NAME, "part1"));
+            add(new AtlasStruct(TestUtilsV2.PARTITION_STRUCT_TYPE, TestUtilsV2.NAME, "part2"));
+        }};
+        tableEntity.setAttribute("partitions", partitions);
+
+        init();
+        EntityMutationResponse response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false);
+        AtlasEntityHeader updatedTable = response.getFirstUpdatedEntityByTypeName(TABLE_TYPE);
+        validateEntity(entitiesInfo, getEntityFromStore(updatedTable));
+
+        //add a new element to array of struct
+        partitions.add(new AtlasStruct(TestUtilsV2.PARTITION_STRUCT_TYPE, TestUtilsV2.NAME, "part3"));
+        init();
+        response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false);
+        updatedTable = response.getFirstUpdatedEntityByTypeName(TABLE_TYPE);
+        validateEntity(entitiesInfo, getEntityFromStore(updatedTable));
+
+        //remove one of the struct values
+        init();
+        partitions.remove(1);
+        response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false);
+        updatedTable = response.getFirstUpdatedEntityByTypeName(TABLE_TYPE);
+        validateEntity(entitiesInfo, getEntityFromStore(updatedTable));
+
+        //Update struct value within array of struct
+        init();
+        partitions.get(0).setAttribute(TestUtilsV2.NAME, "part4");
+        response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false);
+        updatedTable = response.getFirstUpdatedEntityByTypeName(TABLE_TYPE);
+        validateEntity(entitiesInfo, getEntityFromStore(updatedTable));
+
+
+        //add a repeated element to array of struct
+        partitions.add(new AtlasStruct(TestUtilsV2.PARTITION_STRUCT_TYPE, TestUtilsV2.NAME, "part4"));
+        init();
+        response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false);
+        updatedTable = response.getFirstUpdatedEntityByTypeName(TABLE_TYPE);
+        validateEntity(entitiesInfo, getEntityFromStore(updatedTable));
+
+        // Remove all elements. Should set array attribute to null
+        partitions.clear();
+        init();
+        response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false);
+        updatedTable = response.getFirstUpdatedEntityByTypeName(TABLE_TYPE);
+        validateEntity(entitiesInfo, getEntityFromStore(updatedTable));
+    }
+
+
+    @Test(dependsOnMethods = "testCreate")
+    public void testStructs() throws Exception {
+        AtlasEntity              databaseEntity = dbEntity.getEntity();
+        AtlasEntity              tableEntity    = new AtlasEntity(tblEntity.getEntity());
+        AtlasEntitiesWithExtInfo entitiesInfo   = new AtlasEntitiesWithExtInfo(tableEntity);
+
+        AtlasStruct serdeInstance = new AtlasStruct(TestUtilsV2.SERDE_TYPE, TestUtilsV2.NAME, "serde1Name");
+        serdeInstance.setAttribute("serde", "test");
+        serdeInstance.setAttribute("description", "testDesc");
+        tableEntity.setAttribute("serde1", serdeInstance);
+        tableEntity.setAttribute("database", new AtlasObjectId(databaseEntity.getTypeName(), TestUtilsV2.NAME, databaseEntity.getAttribute(TestUtilsV2.NAME)));
+
+        init();
+        EntityMutationResponse response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false);
+        AtlasEntityHeader updatedTable = response.getFirstUpdatedEntityByTypeName(TABLE_TYPE);
+        validateEntity(entitiesInfo, getEntityFromStore(updatedTable));
+
+        //update struct attribute
+        serdeInstance.setAttribute("serde", "testUpdated");
+        init();
+        response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false);
+        updatedTable = response.getFirstUpdatedEntityByTypeName(TABLE_TYPE);
+        validateEntity(entitiesInfo, getEntityFromStore(updatedTable));
+
+        //set to null
+        tableEntity.setAttribute("description", null);
+        init();
+        response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false);
+        updatedTable = response.getFirstUpdatedEntityByTypeName(TABLE_TYPE);
+        Assert.assertNull(updatedTable.getAttribute("description"));
+        validateEntity(entitiesInfo, getEntityFromStore(updatedTable));
+    }
+
+    @Test(dependsOnMethods = "testCreate")
+    public void testClassUpdate() throws Exception {
+
+        init();
+        //Create new db instance
+        final AtlasEntity databaseInstance = TestUtilsV2.createDBEntity();
+
+        EntityMutationResponse response = entityStore.createOrUpdate(new AtlasEntityStream(databaseInstance), false);
+        final AtlasEntityHeader dbCreated = response.getFirstCreatedEntityByTypeName(TestUtilsV2.DATABASE_TYPE);
+
+        init();
+        Map<String, AtlasEntity> tableCloneMap = new HashMap<>();
+        AtlasEntity tableClone = new AtlasEntity(tblEntity.getEntity());
+        tableClone.setAttribute("database", new AtlasObjectId(dbCreated.getGuid(), TestUtilsV2.DATABASE_TYPE));
+
+        tableCloneMap.put(dbCreated.getGuid(), databaseInstance);
+        tableCloneMap.put(tableClone.getGuid(), tableClone);
+
+        response = entityStore.createOrUpdate(new InMemoryMapEntityStream(tableCloneMap), false);
+        final AtlasEntityHeader tableDefinition = response.getFirstUpdatedEntityByTypeName(TABLE_TYPE);
+        AtlasEntity updatedTableDefinition = getEntityFromStore(tableDefinition);
+        Assert.assertNotNull(updatedTableDefinition.getAttribute("database"));
+        Assert.assertEquals(((AtlasObjectId) updatedTableDefinition.getAttribute("database")).getGuid(), dbCreated.getGuid());
+    }
+
+    @Test
+    public void testCheckOptionalAttrValueRetention() throws Exception {
+
+        AtlasEntity dbEntity = TestUtilsV2.createDBEntity();
+
+        init();
+        EntityMutationResponse response = entityStore.createOrUpdate(new AtlasEntityStream(dbEntity), false);
+        AtlasEntity firstEntityCreated = getEntityFromStore(response.getFirstCreatedEntityByTypeName(TestUtilsV2.DATABASE_TYPE));
+
+        //The optional boolean attribute should have a non-null value
+        final String isReplicatedAttr = "isReplicated";
+        final String paramsAttr = "parameters";
+        Assert.assertNotNull(firstEntityCreated.getAttribute(isReplicatedAttr));
+        Assert.assertEquals(firstEntityCreated.getAttribute(isReplicatedAttr), Boolean.FALSE);
+        Assert.assertNull(firstEntityCreated.getAttribute(paramsAttr));
+
+        //Update to true
+        dbEntity.setAttribute(isReplicatedAttr, Boolean.TRUE);
+        //Update array
+        final HashMap<String, String> params = new HashMap<String, String>() {{ put("param1", "val1"); put("param2", "val2"); }};
+        dbEntity.setAttribute(paramsAttr, params);
+        //Complete update
+
+        init();
+        response = entityStore.createOrUpdate(new AtlasEntityStream(dbEntity), false);
+        AtlasEntity firstEntityUpdated = getEntityFromStore(response.getFirstUpdatedEntityByTypeName(TestUtilsV2.DATABASE_TYPE));
+
+        Assert.assertNotNull(firstEntityUpdated);
+        Assert.assertNotNull(firstEntityUpdated.getAttribute(isReplicatedAttr));
+        Assert.assertEquals(firstEntityUpdated.getAttribute(isReplicatedAttr), Boolean.TRUE);
+        Assert.assertEquals(firstEntityUpdated.getAttribute(paramsAttr), params);
+
+        //TODO - enable test after GET API is ready
+//        init();
+//        //Complete update without setting the attribute
+//        AtlasEntity newEntity = TestUtilsV2.createDBEntity();
+//        //Reset name to the current DB name
+//        newEntity.setAttribute(AtlasClient.NAME, firstEntityCreated.getAttribute(AtlasClient.NAME));
+//        response = entityStore.createOrUpdate(newEntity);
+//
+//        firstEntityUpdated = response.getFirstEntityUpdated();
+//        Assert.assertNotNull(firstEntityUpdated.getAttribute(isReplicatedAttr));
+//        Assert.assertEquals(firstEntityUpdated.getAttribute(isReplicatedAttr), Boolean.TRUE);
+//        Assert.assertEquals(firstEntityUpdated.getAttribute(paramsAttr), params);
+    }
+
+    @Test(enabled = false)
+    //Titan doesn't allow some reserved chars in property keys. Verify that atlas encodes these
+    //See GraphHelper.encodePropertyKey()
+    //TODO : Failing in typedef creation
+    public void testSpecialCharacters() throws Exception {
+        //Verify that type can be created with reserved characters in typename, attribute name
+        final String typeName = TestUtilsV2.randomString(10);
+        String strAttrName = randomStrWithReservedChars();
+        String arrayAttrName = randomStrWithReservedChars();
+        String mapAttrName = randomStrWithReservedChars();
+
+        AtlasEntityDef typeDefinition =
+            AtlasTypeUtil.createClassTypeDef(typeName, "Special chars test type", ImmutableSet.<String>of(),
+                AtlasTypeUtil.createOptionalAttrDef(strAttrName, "string"),
+                AtlasTypeUtil.createOptionalAttrDef(arrayAttrName, "array<string>"),
+                AtlasTypeUtil.createOptionalAttrDef(mapAttrName, "map<string,string>"));
+
+        AtlasTypesDef atlasTypesDef = new AtlasTypesDef(null, null, null, Arrays.asList(typeDefinition));
+        typeDefStore.createTypesDef(atlasTypesDef);
+
+        //verify that entity can be created with reserved characters in string value, array value and map key and value
+        AtlasEntity entity = new AtlasEntity();
+        entity.setAttribute(strAttrName, randomStrWithReservedChars());
+        entity.setAttribute(arrayAttrName, new String[]{randomStrWithReservedChars()});
+        entity.setAttribute(mapAttrName, new HashMap<String, String>() {{
+            put(randomStrWithReservedChars(), randomStrWithReservedChars());
+        }});
+
+        AtlasEntityWithExtInfo entityWithExtInfo = new AtlasEntityWithExtInfo(entity);
+
+        final EntityMutationResponse response = entityStore.createOrUpdate(new AtlasEntityStream(entityWithExtInfo), false);
+        final AtlasEntityHeader firstEntityCreated = response.getFirstEntityCreated();
+        validateEntity(entityWithExtInfo, getEntityFromStore(firstEntityCreated));
+
+
+        //Verify that search with reserved characters works - for string attribute
+//        String query =
+//            String.format("`%s` where `%s` = '%s'", typeName, strAttrName, entity.getAttribute(strAttrName));
+//        String responseJson = discoveryService.searchByDSL(query, new QueryParams(1, 0));
+//        JSONObject response = new JSONObject(responseJson);
+//        assertEquals(response.getJSONArray("rows").length(), 1);
+    }
+
+    @Test(expectedExceptions = AtlasBaseException.class)
+    public void testCreateRequiredAttrNull() throws Exception {
+        //Update required attribute
+        Map<String, AtlasEntity> tableCloneMap = new HashMap<>();
+        AtlasEntity tableEntity = new AtlasEntity(TABLE_TYPE);
+        tableEntity.setAttribute(TestUtilsV2.NAME, "table_" + TestUtilsV2.randomString());
+        tableCloneMap.put(tableEntity.getGuid(), tableEntity);
+
+        entityStore.createOrUpdate(new InMemoryMapEntityStream(tableCloneMap), false);
+        Assert.fail("Expected exception while creating with required attribute null");
+    }
+
+    @Test
+    public void testPartialUpdateAttr() throws Exception {
+        //Update optional attribute
+
+        init();
+
+        AtlasEntity dbEntity = new AtlasEntity(TestUtilsV2.DATABASE_TYPE);
+        dbEntity.setAttribute("name", TestUtilsV2.randomString(10));
+        dbEntity.setAttribute("description", "us db");
+        dbEntity.setAttribute("isReplicated", false);
+        dbEntity.setAttribute("created", "09081988");
+        dbEntity.setAttribute("namespace", "db namespace");
+        dbEntity.setAttribute("cluster", "Fenton_Cluster");
+        dbEntity.setAttribute("colo", "10001");
+
+        EntityStream           dbStream        = new AtlasEntityStream(new AtlasEntitiesWithExtInfo(dbEntity));
+        EntityMutationResponse response        = entityStore.createOrUpdate(dbStream, false);
+        AtlasEntityHeader      dbHeader        = response.getFirstEntityCreated();
+        AtlasEntity            createdDbEntity = getEntityFromStore(dbHeader);
+
+        // update the db entity
+        dbEntity = new AtlasEntity(TestUtilsV2.DATABASE_TYPE);
+        dbEntity.setGuid(createdDbEntity.getGuid());
+        // dbEntity.setAttribute("name", createdDbEntity.getAttribute("name"));
+        // dbEntity.setAttribute("description", "another db"); // required attr
+        dbEntity.setAttribute("created", "08151947");       // optional attr
+        dbEntity.setAttribute("isReplicated", true);       // optional attr
+
+        dbStream = new AtlasEntityStream(new AtlasEntitiesWithExtInfo(dbEntity));
+
+        // fail full update if required attributes are not specified.
+        try {
+            entityStore.createOrUpdate(dbStream, false);
+        } catch (AtlasBaseException ex) {
+            Assert.assertEquals(ex.getAtlasErrorCode(), AtlasErrorCode.INSTANCE_CRUD_INVALID_PARAMS);
+        }
+
+        // do partial update without providing required attributes
+        dbStream.reset();
+        response = entityStore.createOrUpdate(dbStream, true);
+        dbHeader = response.getFirstEntityPartialUpdated();
+        AtlasEntity updatedDbEntity = getEntityFromStore(dbHeader);
+
+        assertEquals(updatedDbEntity.getAttribute("name"), createdDbEntity.getAttribute("name"));
+        assertEquals(updatedDbEntity.getAttribute("description"), createdDbEntity.getAttribute("description"));
+        assertEquals(updatedDbEntity.getAttribute("isReplicated"), true);
+        assertEquals(updatedDbEntity.getAttribute("created"), "08151947");
+        assertEquals(updatedDbEntity.getAttribute("namespace"), createdDbEntity.getAttribute("namespace"));
+        assertEquals(updatedDbEntity.getAttribute("cluster"), createdDbEntity.getAttribute("cluster"));
+        assertEquals(updatedDbEntity.getAttribute("colo"), createdDbEntity.getAttribute("colo"));
+
+        // create a new table type
+        AtlasEntity tblEntity = new AtlasEntity(TABLE_TYPE);
+        tblEntity.setAttribute("name", TestUtilsV2.randomString(10));
+        tblEntity.setAttribute("type", "type");
+        tblEntity.setAttribute("tableType", "MANAGED");
+        tblEntity.setAttribute("database", AtlasTypeUtil.getAtlasObjectId(updatedDbEntity));
+
+        // create new column entity
+        AtlasEntity col1 = TestUtilsV2.createColumnEntity(tblEntity);
+        AtlasEntity col2 = TestUtilsV2.createColumnEntity(tblEntity);
+        col1.setAttribute(TestUtilsV2.NAME, "col1");
+        col2.setAttribute(TestUtilsV2.NAME, "col2");
+
+        List<AtlasObjectId> columns = new ArrayList<>();
+        columns.add(AtlasTypeUtil.getAtlasObjectId(col1));
+        columns.add(AtlasTypeUtil.getAtlasObjectId(col2));
+
+        tblEntity.setAttribute(TestUtilsV2.COLUMNS_ATTR_NAME, columns);
+
+        AtlasEntitiesWithExtInfo tableEntityInfo = new AtlasEntitiesWithExtInfo(tblEntity);
+        tableEntityInfo.addReferredEntity(col1.getGuid(), col1);
+        tableEntityInfo.addReferredEntity(col2.getGuid(), col2);
+
+        EntityStream tblStream = new AtlasEntityStream(tableEntityInfo);
+        response = entityStore.createOrUpdate(tblStream, false);
+        AtlasEntityHeader tblHeader = response.getFirstEntityCreated();
+        AtlasEntity createdTblEntity = getEntityFromStore(tblHeader);
+
+        columns = (List<AtlasObjectId>) createdTblEntity.getAttribute(TestUtilsV2.COLUMNS_ATTR_NAME);
+        assertEquals(columns.size(), 2);
+
+        // update - add 2 more columns to table
+        AtlasEntity col3 = TestUtilsV2.createColumnEntity(createdTblEntity);
+        col3.setAttribute(TestUtilsV2.NAME, "col3");
+        col3.setAttribute("description", "description col3");
+
+        AtlasEntity col4 = TestUtilsV2.createColumnEntity(createdTblEntity);
+        col4.setAttribute(TestUtilsV2.NAME, "col4");
+        col4.setAttribute("description", "description col4");
+
+        columns.clear();
+        columns.add(AtlasTypeUtil.getAtlasObjectId(col3));
+        columns.add(AtlasTypeUtil.getAtlasObjectId(col4));
+
+        tblEntity = new AtlasEntity(TABLE_TYPE);
+        tblEntity.setGuid(createdTblEntity.getGuid());
+        tblEntity.setAttribute(TestUtilsV2.COLUMNS_ATTR_NAME, columns);
+
+        tableEntityInfo = new AtlasEntitiesWithExtInfo(tblEntity);
+        tableEntityInfo.addReferredEntity(col3.getGuid(), col3);
+        tableEntityInfo.addReferredEntity(col4.getGuid(), col4);
+
+        tblStream = new AtlasEntityStream(tableEntityInfo);
+        response  = entityStore.createOrUpdate(tblStream, true);
+        tblHeader = response.getFirstEntityPartialUpdated();
+        AtlasEntity updatedTblEntity = getEntityFromStore(tblHeader);
+
+        columns = (List<AtlasObjectId>) updatedTblEntity.getAttribute(TestUtilsV2.COLUMNS_ATTR_NAME);
+        // deleted columns are included in the attribute; hence use >=
+        assertTrue(columns.size() >= 2);
+    }
+
+    @Test
+    public void testPartialUpdateArrayAttr() throws Exception {
+        // Create a table entity, with 3 reference column entities
+        init();
+        final AtlasEntity      dbEntity           = TestUtilsV2.createDBEntity();
+        EntityMutationResponse dbCreationResponse = entityStore.createOrUpdate(new AtlasEntityStream(dbEntity), false);
+
+        final AtlasEntity        tableEntity      = TestUtilsV2.createTableEntity(dbEntity);
+        AtlasEntitiesWithExtInfo entitiesInfo     = new AtlasEntitiesWithExtInfo(tableEntity);
+
+        final AtlasEntity columnEntity1 = TestUtilsV2.createColumnEntity(tableEntity);
+        columnEntity1.setAttribute("description", "desc for col1");
+        entitiesInfo.addReferredEntity(columnEntity1);
+
+        final AtlasEntity columnEntity2 = TestUtilsV2.createColumnEntity(tableEntity);
+        columnEntity2.setAttribute("description", "desc for col2");
+        entitiesInfo.addReferredEntity(columnEntity2);
+
+        final AtlasEntity columnEntity3 = TestUtilsV2.createColumnEntity(tableEntity);
+        columnEntity3.setAttribute("description", "desc for col3");
+        entitiesInfo.addReferredEntity(columnEntity3);
+
+        tableEntity.setAttribute(COLUMNS_ATTR_NAME, Arrays.asList(AtlasTypeUtil.getAtlasObjectId(columnEntity1),
+                                                                  AtlasTypeUtil.getAtlasObjectId(columnEntity2),
+                                                                  AtlasTypeUtil.getAtlasObjectId(columnEntity3)));
+
+        init();
+
+        final EntityMutationResponse tblCreationResponse = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false);
+        final AtlasEntityHeader      createdTblHeader    = tblCreationResponse.getCreatedEntityByTypeNameAndAttribute(TABLE_TYPE, NAME, (String) tableEntity.getAttribute(NAME));
+        final AtlasEntity            createdTblEntity    = getEntityFromStore(createdTblHeader);
+
+        final AtlasEntityHeader column1Created = tblCreationResponse.getCreatedEntityByTypeNameAndAttribute(COLUMN_TYPE, NAME, (String) columnEntity1.getAttribute(NAME));
+        final AtlasEntityHeader column2Created = tblCreationResponse.getCreatedEntityByTypeNameAndAttribute(COLUMN_TYPE, NAME, (String) columnEntity2.getAttribute(NAME));
+        final AtlasEntityHeader column3Created = tblCreationResponse.getCreatedEntityByTypeNameAndAttribute(COLUMN_TYPE, NAME, (String) columnEntity3.getAttribute(NAME));
+
+        // update only description attribute of all 3 columns
+        AtlasEntity col1 = new AtlasEntity(COLUMN_TYPE);
+        col1.setGuid(column1Created.getGuid());
+        col1.setAttribute("description", "desc for col1:updated");
+
+        AtlasEntity col2 = new AtlasEntity(COLUMN_TYPE);
+        col2.setGuid(column2Created.getGuid());
+        col2.setAttribute("description", "desc for col2:updated");
+
+        AtlasEntity col3 = new AtlasEntity(COLUMN_TYPE);
+        col3.setGuid(column3Created.getGuid());
+        col3.setAttribute("description", "desc for col3:updated");
+
+        final AtlasEntity tableEntity1 = new AtlasEntity(TABLE_TYPE);
+        tableEntity1.setGuid(createdTblHeader.getGuid());
+        tableEntity1.setAttribute(COLUMNS_ATTR_NAME, Arrays.asList(AtlasTypeUtil.getAtlasObjectId(col1),
+                AtlasTypeUtil.getAtlasObjectId(col2),
+                AtlasTypeUtil.getAtlasObjectId(col3)));
+        AtlasEntitiesWithExtInfo tableInfo = new AtlasEntitiesWithExtInfo(tableEntity1);
+        tableInfo.addReferredEntity(col1.getGuid(), col1);
+        tableInfo.addReferredEntity(col2.getGuid(), col2);
+        tableInfo.addReferredEntity(col3.getGuid(), col3);
+
+        init();
+
+        final EntityMutationResponse tblUpdateResponse = entityStore.createOrUpdate(new AtlasEntityStream(tableInfo), true);
+        final AtlasEntityHeader      updatedTblHeader  = tblUpdateResponse.getFirstEntityPartialUpdated();
+        final AtlasEntity            updatedTblEntity2 = getEntityFromStore(updatedTblHeader);
+        List<AtlasEntityHeader>      updatedColHeaders = tblUpdateResponse.getPartialUpdatedEntitiesByTypeName(COLUMN_TYPE);
+
+        final AtlasEntity updatedCol1Entity = getEntityFromStore(updatedColHeaders.get(0));
+        final AtlasEntity updatedCol2Entity = getEntityFromStore(updatedColHeaders.get(1));
+        final AtlasEntity updatedCol3Entity = getEntityFromStore(updatedColHeaders.get(2));
+
+        assertEquals(col1.getAttribute("description"), updatedCol1Entity.getAttribute("description"));
+        assertEquals(col2.getAttribute("description"), updatedCol2Entity.getAttribute("description"));
+        assertEquals(col3.getAttribute("description"), updatedCol3Entity.getAttribute("description"));
+    }
+
+    @Test
+    public void testSetObjectIdAttrToNull() throws Exception {
+        final AtlasEntity dbEntity  = TestUtilsV2.createDBEntity();
+        final AtlasEntity db2Entity = TestUtilsV2.createDBEntity();
+
+        entityStore.createOrUpdate(new AtlasEntityStream(dbEntity), false);
+        entityStore.createOrUpdate(new AtlasEntityStream(db2Entity), false);
+
+        final AtlasEntity tableEntity = TestUtilsV2.createTableEntity(dbEntity);
+
+        tableEntity.setAttribute("databaseComposite", AtlasTypeUtil.getAtlasObjectId(db2Entity));
+
+        final EntityMutationResponse tblCreationResponse = entityStore.createOrUpdate(new AtlasEntityStream(tableEntity), false);
+        final AtlasEntityHeader      createdTblHeader    = tblCreationResponse.getCreatedEntityByTypeNameAndAttribute(TABLE_TYPE, NAME, (String) tableEntity.getAttribute(NAME));
+        final AtlasEntity            createdTblEntity    = getEntityFromStore(createdTblHeader);
+
+        init();
+
+        createdTblEntity.setAttribute("databaseComposite", null);
+
+        final EntityMutationResponse tblUpdateResponse = entityStore.createOrUpdate(new AtlasEntityStream(createdTblEntity), true);
+        final AtlasEntityHeader      updatedTblHeader  = tblUpdateResponse.getFirstEntityPartialUpdated();
+        final AtlasEntity            updatedTblEntity  = getEntityFromStore(updatedTblHeader);
+        final AtlasEntity            deletedDb2Entity  = getEntityFromStore(db2Entity.getGuid());
+
+        assertEquals(deletedDb2Entity.getStatus(), AtlasEntity.Status.DELETED);
+    }
+
+    @Test
+    public void testTagAssociationAfterRedefinition(){
+        AtlasClassificationDef aTag = new AtlasClassificationDef("testTag");
+        AtlasAttributeDef attributeDef = new AtlasAttributeDef("testAttribute", "int", true,
+                AtlasAttributeDef.Cardinality.SINGLE, 0, 1,
+                false, true,
+                Collections.<AtlasStructDef.AtlasConstraintDef>emptyList());
+        aTag.addAttribute(attributeDef);
+
+        AtlasTypesDef typesDef = new AtlasTypesDef();
+        typesDef.setClassificationDefs(Arrays.asList(aTag));
+
+        try {
+            typeDefStore.createTypesDef(typesDef);
+        } catch (AtlasBaseException e) {
+            fail("Tag creation should've succeeded");
+        }
+
+        try {
+            typeDefStore.deleteTypesDef(typesDef);
+        } catch (AtlasBaseException e) {
+            fail("Tag deletion should've succeeded");
+        }
+
+        aTag = new AtlasClassificationDef("testTag");
+        attributeDef = new AtlasAttributeDef("testAttribute", "string", true,
+                AtlasAttributeDef.Cardinality.SINGLE, 0, 1,
+                false, true,
+                Collections.<AtlasStructDef.AtlasConstraintDef>emptyList());
+        aTag.addAttribute(attributeDef);
+        typesDef.setClassificationDefs(Arrays.asList(aTag));
+
+        try {
+            typeDefStore.createTypesDef(typesDef);
+        } catch (AtlasBaseException e) {
+            fail("Tag re-creation should've succeeded");
+        }
+
+        final AtlasEntity dbEntity  = TestUtilsV2.createDBEntity();
+
+        try {
+            EntityMutationResponse response = entityStore.createOrUpdate(new AtlasEntityStream(dbEntity), false);
+            List<AtlasEntityHeader> createdEntity = response.getCreatedEntities();
+            assertTrue(CollectionUtils.isNotEmpty(createdEntity));
+            String guid = createdEntity.get(0).getGuid();
+            entityStore.addClassification(Arrays.asList(guid), new AtlasClassification(aTag.getName(), "testAttribute", "test-string"));
+        } catch (AtlasBaseException e) {
+            fail("DB entity creation should've succeeded, e.getMessage() => " + e.getMessage());
+        }
+
+    }
+
+    private String randomStrWithReservedChars() {
+        return randomString() + "\"${}%";
+    }
+
+    private void validateMutationResponse(EntityMutationResponse response, EntityMutations.EntityOperation op, int expectedNumCreated) {
+        List<AtlasEntityHeader> entitiesCreated = response.getEntitiesByOperation(op);
+        Assert.assertNotNull(entitiesCreated);
+        Assert.assertEquals(entitiesCreated.size(), expectedNumCreated);
+    }
+
+    private void validateEntity(AtlasEntityExtInfo entityExtInfo, AtlasEntity actual) throws AtlasBaseException, AtlasException {
+        validateEntity(entityExtInfo, actual, entityExtInfo.getEntity(actual.getGuid()));
+    }
+
+    private void validateEntity(AtlasEntityExtInfo entityExtInfo, AtlasStruct actual, AtlasStruct expected) throws AtlasBaseException, AtlasException {
+        if (expected == null) {
+            Assert.assertNull(actual, "expected null instance. Found " + actual);
+
+            return;
+        }
+
+        Assert.assertNotNull(actual, "found null instance");
+
+        AtlasStructType entityType = (AtlasStructType) typeRegistry.getType(actual.getTypeName());
+        for (String attrName : expected.getAttributes().keySet()) {
+            Object expectedVal = expected.getAttribute(attrName);
+            Object actualVal   = actual.getAttribute(attrName);
+
+            AtlasType attrType = entityType.getAttributeType(attrName);
+            validateAttribute(entityExtInfo, actualVal, expectedVal, attrType, attrName);
+        }
+    }
+
+    private void validateAttribute(AtlasEntityExtInfo entityExtInfo, Object actual, Object expected, AtlasType attributeType, String attrName) throws AtlasBaseException, AtlasException {
+        switch(attributeType.getTypeCategory()) {
+            case OBJECT_ID_TYPE:
+                Assert.assertTrue(actual instanceof AtlasObjectId);
+                String guid = ((AtlasObjectId) actual).getGuid();
+                Assert.assertTrue(AtlasTypeUtil.isAssignedGuid(guid), "expected assigned guid. found " + guid);
+                break;
+
+            case PRIMITIVE:
+            case ENUM:
+                Assert.assertEquals(actual, expected);
+                break;
+
+            case MAP:
+                AtlasMapType mapType     = (AtlasMapType) attributeType;
+                AtlasType    valueType   = mapType.getValueType();
+                Map          actualMap   = (Map) actual;
+                Map          expectedMap = (Map) expected;
+
+                if (MapUtils.isNotEmpty(expectedMap)) {
+                    Assert.assertTrue(MapUtils.isNotEmpty(actualMap));
+
+                    // deleted entries are included in the attribute; hence use >=
+                    Assert.assertTrue(actualMap.size() >= expectedMap.size());
+
+                    for (Object key : expectedMap.keySet()) {
+                        validateAttribute(entityExtInfo, actualMap.get(key), expectedMap.get(key), valueType, attrName);
+                    }
+                }
+                break;
+
+            case ARRAY:
+                AtlasArrayType arrType      = (AtlasArrayType) attributeType;
+                AtlasType      elemType     = arrType.getElementType();
+                List           actualList   = (List) actual;
+                List           expectedList = (List) expected;
+
+                if (CollectionUtils.isNotEmpty(expectedList)) {
+                    Assert.assertTrue(CollectionUtils.isNotEmpty(actualList));
+
+                    //actual list could have deleted entities. Hence size may not match.
+                    Assert.assertTrue(actualList.size() >= expectedList.size());
+
+                    for (int i = 0; i < expectedList.size(); i++) {
+                        validateAttribute(entityExtInfo, actualList.get(i), expectedList.get(i), elemType, attrName);
+                    }
+                }
+                break;
+            case STRUCT:
+                AtlasStruct expectedStruct = (AtlasStruct) expected;
+                AtlasStruct actualStruct   = (AtlasStruct) actual;
+
+                validateEntity(entityExtInfo, actualStruct, expectedStruct);
+                break;
+            default:
+                Assert.fail("Unknown type category");
+        }
+    }
+
+    private AtlasEntity getEntityFromStore(AtlasEntityHeader header) throws AtlasBaseException {
+        return header != null ? getEntityFromStore(header.getGuid()) : null;
+    }
+
+    private AtlasEntity getEntityFromStore(String guid) throws AtlasBaseException {
+        AtlasEntityWithExtInfo entity = guid != null ? entityStore.getById(guid) : null;
+
+        return entity != null ? entity.getEntity() : null;
+    }
+}
diff --git a/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasRelationshipDefStoreV1Test.java b/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasRelationshipDefStoreV1Test.java
new file mode 100644
index 0000000..59bedd1
--- /dev/null
+++ b/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasRelationshipDefStoreV1Test.java
@@ -0,0 +1,330 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.repository.store.graph.v1;
+
+import com.google.inject.Inject;
+import org.apache.atlas.ApplicationProperties;
+import org.apache.atlas.AtlasErrorCode;
+import org.apache.atlas.AtlasException;
+import org.apache.atlas.TestModules;
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.typedef.AtlasRelationshipDef;
+import org.apache.atlas.model.typedef.AtlasRelationshipEndDef;
+import org.apache.atlas.model.typedef.AtlasStructDef;
+import org.apache.atlas.repository.graph.AtlasGraphProvider;
+import org.apache.atlas.type.AtlasTypeUtil;
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+
+import static org.testng.AssertJUnit.fail;
+
+/**
+ * Tests for AtlasRelationshipStoreV1
+ */
+@Guice(modules = TestModules.TestOnlyModule.class)
+public class AtlasRelationshipDefStoreV1Test {
+
+    @Inject
+    private
+    AtlasRelationshipDefStoreV1 relationshipDefStore;
+
+    @DataProvider
+    public Object[][] invalidAttributeNameWithReservedKeywords(){
+        AtlasRelationshipDef invalidAttrNameType =
+            AtlasTypeUtil.createRelationshipTypeDef("Invalid_Attribute_Type", "description","" ,
+                    AtlasRelationshipDef.RelationshipCategory.ASSOCIATION,
+                    AtlasRelationshipDef.PropagateTags.BOTH,
+                    new AtlasRelationshipEndDef("typeA", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
+                    new AtlasRelationshipEndDef("typeB", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
+
+                    AtlasTypeUtil.createRequiredAttrDef("order", "string"),
+                    AtlasTypeUtil.createRequiredAttrDef("limit", "string"));
+
+        return new Object[][] {{
+            invalidAttrNameType
+        }};
+    }
+    @DataProvider
+    public Object[][] updateValidProperties(){
+        AtlasRelationshipDef existingType =
+                AtlasTypeUtil.createRelationshipTypeDef("basicType", "description","0" ,
+                        AtlasRelationshipDef.RelationshipCategory.ASSOCIATION,
+                        AtlasRelationshipDef.PropagateTags.ONE_TO_TWO,
+                        new AtlasRelationshipEndDef("typeC", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
+                        new AtlasRelationshipEndDef("typeD", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
+
+                        AtlasTypeUtil.createRequiredAttrDef("aaaa", "string"),
+                        AtlasTypeUtil.createRequiredAttrDef("bbbb", "string"));
+        AtlasRelationshipDef newType =
+                AtlasTypeUtil.createRelationshipTypeDef("basicType",
+                        "description1", // updated
+                        "1" , // updated
+                        AtlasRelationshipDef.RelationshipCategory.ASSOCIATION,
+                        AtlasRelationshipDef.PropagateTags.BOTH, // updated
+                        new AtlasRelationshipEndDef("typeC", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
+                        new AtlasRelationshipEndDef("typeD", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
+
+                        AtlasTypeUtil.createRequiredAttrDef("aaaa", "string"),
+                        AtlasTypeUtil.createRequiredAttrDef("bbbb", "string"));
+
+
+        return new Object[][] {{
+                existingType,
+                newType
+        }};
+    }
+
+
+    @DataProvider
+    public Object[][] updateRename(){
+        AtlasRelationshipDef existingType =
+                AtlasTypeUtil.createRelationshipTypeDef("basicType", "description","" ,
+                        AtlasRelationshipDef.RelationshipCategory.ASSOCIATION,
+                        AtlasRelationshipDef.PropagateTags.BOTH,
+                        new AtlasRelationshipEndDef("typeC", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
+                        new AtlasRelationshipEndDef("typeD", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
+
+                        AtlasTypeUtil.createRequiredAttrDef("aaaa", "string"),
+                        AtlasTypeUtil.createRequiredAttrDef("bbbb", "string"));
+        AtlasRelationshipDef newType =
+                AtlasTypeUtil.createRelationshipTypeDef("basicType2", "description","" ,
+                        AtlasRelationshipDef.RelationshipCategory.ASSOCIATION,
+                        AtlasRelationshipDef.PropagateTags.BOTH,
+                        new AtlasRelationshipEndDef("typeC", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
+                        new AtlasRelationshipEndDef("typeD", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
+
+                        AtlasTypeUtil.createRequiredAttrDef("aaaa", "string"),
+                        AtlasTypeUtil.createRequiredAttrDef("bbbb", "string"));
+
+
+        return new Object[][] {{
+                existingType,
+                newType
+        }};
+    }
+    @DataProvider
+    public Object[][] updateRelCat(){
+        AtlasRelationshipDef existingType =
+                AtlasTypeUtil.createRelationshipTypeDef("basicType", "description","" ,
+                        AtlasRelationshipDef.RelationshipCategory.ASSOCIATION,
+                        AtlasRelationshipDef.PropagateTags.BOTH,
+                        new AtlasRelationshipEndDef("typeC", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
+                        new AtlasRelationshipEndDef("typeD", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
+
+                        AtlasTypeUtil.createRequiredAttrDef("aaaa", "string"),
+                        AtlasTypeUtil.createRequiredAttrDef("bbbb", "string"));
+        AtlasRelationshipDef newType =
+                AtlasTypeUtil.createRelationshipTypeDef("basicType", "description","" ,
+                        AtlasRelationshipDef.RelationshipCategory.AGGREGATION,
+                        AtlasRelationshipDef.PropagateTags.BOTH,
+                        new AtlasRelationshipEndDef("typeC", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
+                        new AtlasRelationshipEndDef("typeD", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
+
+                        AtlasTypeUtil.createRequiredAttrDef("aaaa", "string"),
+                        AtlasTypeUtil.createRequiredAttrDef("bbbb", "string"));
+
+
+        return new Object[][] {{
+                existingType,
+                newType
+        }};
+    }
+    @DataProvider
+    public Object[][] updateEnd1(){
+        AtlasRelationshipDef existingType =
+                AtlasTypeUtil.createRelationshipTypeDef("basicType", "description","" ,
+                        AtlasRelationshipDef.RelationshipCategory.ASSOCIATION,
+                        AtlasRelationshipDef.PropagateTags.BOTH,
+                        new AtlasRelationshipEndDef("typeC", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
+                        new AtlasRelationshipEndDef("typeD", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
+
+                        AtlasTypeUtil.createRequiredAttrDef("aaaa", "string"),
+                        AtlasTypeUtil.createRequiredAttrDef("bbbb", "string"));
+        AtlasRelationshipDef changeType =
+                AtlasTypeUtil.createRelationshipTypeDef("basicType", "description","" ,
+                        AtlasRelationshipDef.RelationshipCategory.ASSOCIATION,
+                        AtlasRelationshipDef.PropagateTags.BOTH,
+                        new AtlasRelationshipEndDef("typeE", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
+                        new AtlasRelationshipEndDef("typeD", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
+
+                        AtlasTypeUtil.createRequiredAttrDef("aaaa", "string"),
+                        AtlasTypeUtil.createRequiredAttrDef("bbbb", "string"));
+        AtlasRelationshipDef changeAttr =
+                AtlasTypeUtil.createRelationshipTypeDef("basicType", "description","" ,
+                        AtlasRelationshipDef.RelationshipCategory.ASSOCIATION,
+                        AtlasRelationshipDef.PropagateTags.BOTH,
+                        new AtlasRelationshipEndDef("typeC", "attr2", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
+                        new AtlasRelationshipEndDef("typeD", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
+
+                        AtlasTypeUtil.createRequiredAttrDef("aaaa", "string"),
+                        AtlasTypeUtil.createRequiredAttrDef("bbbb", "string"));
+        AtlasRelationshipDef changeCardinality =
+                AtlasTypeUtil.createRelationshipTypeDef("basicType", "description","" ,
+                        AtlasRelationshipDef.RelationshipCategory.ASSOCIATION,
+                        AtlasRelationshipDef.PropagateTags.BOTH,
+                        new AtlasRelationshipEndDef("typeC", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.LIST),
+                        new AtlasRelationshipEndDef("typeD", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
+
+                        AtlasTypeUtil.createRequiredAttrDef("aaaa", "string"),
+                        AtlasTypeUtil.createRequiredAttrDef("bbbb", "string"));
+
+
+        return new Object[][]{
+                {
+                        existingType,
+                        changeType
+                },
+                {
+                        existingType,
+                        changeAttr
+                },
+                {
+                        existingType,
+                        changeCardinality
+                }
+        };
+    }
+    @DataProvider
+    public Object[][] updateEnd2(){
+        AtlasRelationshipDef existingType =
+                AtlasTypeUtil.createRelationshipTypeDef("basicType", "description","" ,
+                        AtlasRelationshipDef.RelationshipCategory.ASSOCIATION,
+                        AtlasRelationshipDef.PropagateTags.BOTH,
+                        new AtlasRelationshipEndDef("typeC", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
+                        new AtlasRelationshipEndDef("typeD", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
+
+                        AtlasTypeUtil.createRequiredAttrDef("aaaa", "string"),
+                        AtlasTypeUtil.createRequiredAttrDef("bbbb", "string"));
+
+        AtlasRelationshipDef changeType =
+                AtlasTypeUtil.createRelationshipTypeDef("basicType", "description","" ,
+                        AtlasRelationshipDef.RelationshipCategory.ASSOCIATION,
+                        AtlasRelationshipDef.PropagateTags.BOTH,
+                        new AtlasRelationshipEndDef("typeC", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
+                        new AtlasRelationshipEndDef("typeE", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
+
+                        AtlasTypeUtil.createRequiredAttrDef("aaaa", "string"),
+                        AtlasTypeUtil.createRequiredAttrDef("bbbb", "string"));
+        AtlasRelationshipDef changeAttr =
+                AtlasTypeUtil.createRelationshipTypeDef("basicType", "description","" ,
+                        AtlasRelationshipDef.RelationshipCategory.ASSOCIATION,
+                        AtlasRelationshipDef.PropagateTags.BOTH,
+                        new AtlasRelationshipEndDef("typeC", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
+                        new AtlasRelationshipEndDef("typeD", "attr2", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
+
+                        AtlasTypeUtil.createRequiredAttrDef("aaaa", "string"),
+                        AtlasTypeUtil.createRequiredAttrDef("bbbb", "string"));
+        AtlasRelationshipDef changeCardinality =
+                AtlasTypeUtil.createRelationshipTypeDef("basicType", "description","" ,
+                        AtlasRelationshipDef.RelationshipCategory.ASSOCIATION,
+                        AtlasRelationshipDef.PropagateTags.BOTH,
+                        new AtlasRelationshipEndDef("typeC", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE),
+                        new AtlasRelationshipEndDef("typeD", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.LIST),
+
+                        AtlasTypeUtil.createRequiredAttrDef("aaaa", "string"),
+                        AtlasTypeUtil.createRequiredAttrDef("bbbb", "string"));
+
+
+        return new Object[][]{
+                {
+                        existingType,
+                        changeType
+                },
+                {
+                        existingType,
+                        changeAttr
+                },
+                {
+                        existingType,
+                        changeCardinality
+                }
+        };
+    }
+
+    @Test(dataProvider = "invalidAttributeNameWithReservedKeywords")
+    public void testCreateTypeWithReservedKeywords(AtlasRelationshipDef atlasRelationshipDef) throws AtlasException {
+        try {
+            ApplicationProperties.get().setProperty(AtlasAbstractDefStoreV1.ALLOW_RESERVED_KEYWORDS, false);
+            relationshipDefStore.create(atlasRelationshipDef, null);
+        } catch (AtlasBaseException e) {
+            Assert.assertEquals(e.getAtlasErrorCode(), AtlasErrorCode.ATTRIBUTE_NAME_INVALID);
+        }
+    }
+
+    @Test(dataProvider = "updateValidProperties")
+    public void testupdateVertexPreUpdatepropagateTags(AtlasRelationshipDef existingRelationshipDef,AtlasRelationshipDef newRelationshipDef) throws AtlasBaseException {
+        AtlasRelationshipDefStoreV1.preUpdateCheck(existingRelationshipDef,newRelationshipDef);
+    }
+
+    @Test(dataProvider = "updateRename")
+    public void testupdateVertexPreUpdateRename(AtlasRelationshipDef existingRelationshipDef,AtlasRelationshipDef newRelationshipDef)  {
+
+        try {
+            AtlasRelationshipDefStoreV1.preUpdateCheck(existingRelationshipDef,newRelationshipDef);
+            fail("expected error");
+        } catch (AtlasBaseException e) {
+            if (!e.getAtlasErrorCode().equals(AtlasErrorCode.RELATIONSHIPDEF_INVALID_NAME_UPDATE)){
+                fail("unexpected AtlasErrorCode "+e.getAtlasErrorCode());
+            }
+        }
+    }
+    @Test(dataProvider = "updateRelCat")
+    public void testupdateVertexPreUpdateRelcat(AtlasRelationshipDef existingRelationshipDef,AtlasRelationshipDef newRelationshipDef)  {
+
+        try {
+            AtlasRelationshipDefStoreV1.preUpdateCheck(existingRelationshipDef,newRelationshipDef);
+            fail("expected error");
+        } catch (AtlasBaseException e) {
+            if (!e.getAtlasErrorCode().equals(AtlasErrorCode.RELATIONSHIPDEF_INVALID_CATEGORY_UPDATE)){
+                fail("unexpected AtlasErrorCode "+e.getAtlasErrorCode());
+            }
+        }
+    }
+    @Test(dataProvider = "updateEnd1")
+    public void testupdateVertexPreUpdateEnd1(AtlasRelationshipDef existingRelationshipDef,AtlasRelationshipDef newRelationshipDef)  {
+
+        try {
+            AtlasRelationshipDefStoreV1.preUpdateCheck(existingRelationshipDef,newRelationshipDef);
+            fail("expected error");
+        } catch (AtlasBaseException e) {
+            if (!e.getAtlasErrorCode().equals(AtlasErrorCode.RELATIONSHIPDEF_INVALID_END1_UPDATE)){
+                fail("unexpected AtlasErrorCode "+e.getAtlasErrorCode());
+            }
+        }
+    }
+
+    @Test(dataProvider = "updateEnd2")
+    public void testupdateVertexPreUpdateEnd2(AtlasRelationshipDef existingRelationshipDef,AtlasRelationshipDef newRelationshipDef)  {
+
+        try {
+            AtlasRelationshipDefStoreV1.preUpdateCheck(existingRelationshipDef,newRelationshipDef);
+            fail("expected error");
+        } catch (AtlasBaseException e) {
+            if (!e.getAtlasErrorCode().equals(AtlasErrorCode.RELATIONSHIPDEF_INVALID_END2_UPDATE)){
+                fail("unexpected AtlasErrorCode "+e.getAtlasErrorCode());
+            }
+        }
+    }
+    @AfterClass
+    public void clear(){
+        AtlasGraphProvider.cleanup();
+    }
+}
diff --git a/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasRelationshipStoreHardDeleteV1Test.java b/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasRelationshipStoreHardDeleteV1Test.java
new file mode 100644
index 0000000..109118e
--- /dev/null
+++ b/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasRelationshipStoreHardDeleteV1Test.java
@@ -0,0 +1,112 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.repository.store.graph.v1;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.atlas.TestModules;
+import org.apache.atlas.model.instance.AtlasEntity;
+import org.apache.atlas.model.instance.AtlasObjectId;
+import org.testng.annotations.Guice;
+
+import java.util.List;
+
+import static org.apache.atlas.type.AtlasTypeUtil.getAtlasObjectId;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+
+/**
+ * Inverse reference update test with {@link HardDeleteHandlerV1}
+ */
+@Guice(modules = TestModules.HardDeleteModule.class)
+public class AtlasRelationshipStoreHardDeleteV1Test extends AtlasRelationshipStoreV1Test {
+
+    @Override
+    protected void verifyRelationshipAttributeUpdate_NonComposite_OneToMany(AtlasEntity jane) throws Exception {
+        // Max should have been removed from the subordinates list, leaving only John.
+        verifyRelationshipAttributeList(jane, "subordinates", ImmutableList.of(employeeNameIdMap.get("John")));
+    }
+
+    @Override
+    protected void verifyRelationshipAttributeUpdate_NonComposite_ManyToOne(AtlasEntity a1, AtlasEntity a2,
+                                                                            AtlasEntity a3, AtlasEntity b) {
+
+        verifyRelationshipAttributeValue(a1, "oneB", null);
+
+        verifyRelationshipAttributeValue(a2, "oneB", null);
+
+        verifyRelationshipAttributeList(b, "manyA", ImmutableList.of(getAtlasObjectId(a3)));
+    }
+
+    @Override
+    protected void verifyRelationshipAttributeUpdate_NonComposite_OneToOne(AtlasEntity a1, AtlasEntity b) {
+        verifyRelationshipAttributeValue(a1, "b", null);
+    }
+
+    @Override
+    protected void verifyRelationshipAttributeUpdate_ManyToMany_Friends(AtlasEntity max, AtlasEntity julius, AtlasEntity mike, AtlasEntity john) throws Exception {
+        AtlasObjectId johnId   = employeeNameIdMap.get("John");
+        AtlasObjectId mikeId   = employeeNameIdMap.get("Mike");
+        AtlasObjectId juliusId = employeeNameIdMap.get("Julius");
+        AtlasObjectId maxId    = employeeNameIdMap.get("Max");
+
+        List<AtlasObjectId> maxFriendsIds = toAtlasObjectIds(max.getRelationshipAttribute("friends"));
+        assertNotNull(maxFriendsIds);
+        assertEquals(maxFriendsIds.size(), 2);
+        assertObjectIdsContains(maxFriendsIds, johnId);
+        assertObjectIdsContains(maxFriendsIds, juliusId);
+
+        // Julius's updated friends: [Max]
+        List<AtlasObjectId> juliusFriendsIds = toAtlasObjectIds(julius.getRelationshipAttribute("friends"));
+        assertNotNull(juliusFriendsIds);
+        assertEquals(juliusFriendsIds.size(), 1);
+        assertObjectIdsContains(juliusFriendsIds, maxId);
+
+        // Mike's updated friends: [John]
+        List<AtlasObjectId> mikeFriendsIds = toAtlasObjectIds(mike.getRelationshipAttribute("friends"));
+        assertNotNull(mikeFriendsIds);
+        assertEquals(mikeFriendsIds.size(), 1);
+        assertObjectIdsContains(mikeFriendsIds, johnId);
+
+        // John's updated friends: [Max, Mike]
+        List<AtlasObjectId> johnFriendsIds = toAtlasObjectIds(john.getRelationshipAttribute("friends"));
+        assertNotNull(johnFriendsIds);
+        assertEquals(johnFriendsIds.size(), 2);
+        assertObjectIdsContains(johnFriendsIds, maxId);
+        assertObjectIdsContains(johnFriendsIds, mikeId);
+    }
+
+    protected void verifyRelationshipAttributeUpdate_OneToOne_Sibling(AtlasEntity julius, AtlasEntity jane, AtlasEntity mike) throws Exception {
+        AtlasObjectId juliusId = employeeNameIdMap.get("Julius");
+        AtlasObjectId mikeId   = employeeNameIdMap.get("Mike");
+
+        // Julius sibling updated to Mike
+        AtlasObjectId juliusSiblingId = toAtlasObjectId(julius.getRelationshipAttribute("sibling"));
+        assertNotNull(juliusSiblingId);
+        assertObjectIdEquals(juliusSiblingId, mikeId);
+
+        // Mike's sibling is Julius
+        AtlasObjectId mikeSiblingId = toAtlasObjectId(mike.getRelationshipAttribute("sibling"));
+        assertNotNull(mikeSiblingId);
+        assertObjectIdEquals(mikeSiblingId, juliusId);
+
+        // Julius removed from Jane's sibling (hard delete)
+        AtlasObjectId janeSiblingId = toAtlasObjectId(jane.getRelationshipAttribute("sibling"));
+        assertNull(janeSiblingId);
+    }
+}
\ No newline at end of file
diff --git a/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasRelationshipStoreSoftDeleteV1Test.java b/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasRelationshipStoreSoftDeleteV1Test.java
new file mode 100644
index 0000000..4faf5ad
--- /dev/null
+++ b/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasRelationshipStoreSoftDeleteV1Test.java
@@ -0,0 +1,116 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.repository.store.graph.v1;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.atlas.TestModules;
+import org.apache.atlas.model.instance.AtlasEntity;
+import org.apache.atlas.model.instance.AtlasObjectId;
+import org.testng.annotations.Guice;
+
+import java.util.List;
+
+import static org.apache.atlas.type.AtlasTypeUtil.getAtlasObjectId;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
+
+/**
+ * Inverse reference update test with {@link SoftDeleteHandlerV1}
+ */
+@Guice(modules = TestModules.SoftDeleteModule.class)
+public class AtlasRelationshipStoreSoftDeleteV1Test extends AtlasRelationshipStoreV1Test {
+
+    @Override
+    protected void verifyRelationshipAttributeUpdate_NonComposite_OneToMany(AtlasEntity jane) throws Exception {
+        // Max is still in the subordinates list, as the edge still exists with state DELETED
+        verifyRelationshipAttributeList(jane, "subordinates", ImmutableList.of(employeeNameIdMap.get("John"), employeeNameIdMap.get("Max")));
+    }
+
+    @Override
+    protected void verifyRelationshipAttributeUpdate_NonComposite_ManyToOne(AtlasEntity a1, AtlasEntity a2,
+                                                                            AtlasEntity a3, AtlasEntity b) {
+
+        verifyRelationshipAttributeValue(a1, "oneB", b.getGuid());
+
+        verifyRelationshipAttributeValue(a2, "oneB", b.getGuid());
+
+        verifyRelationshipAttributeList(b, "manyA", ImmutableList.of(getAtlasObjectId(a1), getAtlasObjectId(a2), getAtlasObjectId(a3)));
+    }
+
+    @Override
+    protected void verifyRelationshipAttributeUpdate_NonComposite_OneToOne(AtlasEntity a1, AtlasEntity b) {
+        verifyRelationshipAttributeValue(a1, "b", b.getGuid());
+    }
+
+    @Override
+    protected void verifyRelationshipAttributeUpdate_ManyToMany_Friends(AtlasEntity max, AtlasEntity julius, AtlasEntity mike, AtlasEntity john) throws Exception {
+        AtlasObjectId johnId   = employeeNameIdMap.get("John");
+        AtlasObjectId mikeId   = employeeNameIdMap.get("Mike");
+        AtlasObjectId juliusId = employeeNameIdMap.get("Julius");
+        AtlasObjectId maxId    = employeeNameIdMap.get("Max");
+
+        // Max's updated friends: [Julius, John, Mike(soft deleted)]
+        List<AtlasObjectId> maxFriendsIds = toAtlasObjectIds(max.getRelationshipAttribute("friends"));
+        assertNotNull(maxFriendsIds);
+        assertEquals(maxFriendsIds.size(), 3);
+        assertObjectIdsContains(maxFriendsIds, johnId);
+        assertObjectIdsContains(maxFriendsIds, juliusId);
+        assertObjectIdsContains(maxFriendsIds, mikeId);
+
+        // Julius's updated friends: [Max]
+        List<AtlasObjectId> juliusFriendsIds = toAtlasObjectIds(julius.getRelationshipAttribute("friends"));
+        assertNotNull(juliusFriendsIds);
+        assertEquals(juliusFriendsIds.size(), 1);
+        assertObjectIdsContains(juliusFriendsIds, maxId);
+
+        // Mike's updated friends: [John, Max(soft deleted)]
+        List<AtlasObjectId> mikeFriendsIds = toAtlasObjectIds(mike.getRelationshipAttribute("friends"));
+        assertNotNull(mikeFriendsIds);
+        assertEquals(mikeFriendsIds.size(), 2);
+        assertObjectIdsContains(mikeFriendsIds, johnId);
+        assertObjectIdsContains(mikeFriendsIds, maxId);
+
+        // John's updated friends: [Max, Mike]
+        List<AtlasObjectId> johnFriendsIds = toAtlasObjectIds(john.getRelationshipAttribute("friends"));
+        assertNotNull(johnFriendsIds);
+        assertEquals(johnFriendsIds.size(), 2);
+        assertObjectIdsContains(johnFriendsIds, maxId);
+        assertObjectIdsContains(johnFriendsIds, mikeId);
+    }
+
+    protected void verifyRelationshipAttributeUpdate_OneToOne_Sibling(AtlasEntity julius, AtlasEntity jane, AtlasEntity mike) throws Exception {
+        AtlasObjectId juliusId = employeeNameIdMap.get("Julius");
+        AtlasObjectId mikeId   = employeeNameIdMap.get("Mike");
+
+        // Julius sibling updated to Mike
+        AtlasObjectId juliusSiblingId = toAtlasObjectId(julius.getRelationshipAttribute("sibling"));
+        assertNotNull(juliusSiblingId);
+        assertObjectIdEquals(juliusSiblingId, mikeId);
+
+        // Mike's sibling is Julius
+        AtlasObjectId mikeSiblingId = toAtlasObjectId(mike.getRelationshipAttribute("sibling"));
+        assertNotNull(mikeSiblingId);
+        assertObjectIdEquals(mikeSiblingId, juliusId);
+
+        // Jane's sibling is still Julius (soft delete)
+        AtlasObjectId janeSiblingId = toAtlasObjectId(jane.getRelationshipAttribute("sibling"));
+        assertNotNull(janeSiblingId);
+        assertObjectIdEquals(janeSiblingId, juliusId);
+    }
+}
\ No newline at end of file
diff --git a/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasRelationshipStoreV1Test.java b/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasRelationshipStoreV1Test.java
new file mode 100644
index 0000000..d207a69
--- /dev/null
+++ b/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasRelationshipStoreV1Test.java
@@ -0,0 +1,623 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.repository.store.graph.v1;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.atlas.RequestContextV1;
+import org.apache.atlas.TestModules;
+import org.apache.atlas.TestUtilsV2;
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.instance.AtlasEntity;
+import org.apache.atlas.model.instance.AtlasEntity.AtlasEntitiesWithExtInfo;
+import org.apache.atlas.model.instance.AtlasEntity.AtlasEntityWithExtInfo;
+import org.apache.atlas.model.instance.AtlasEntityHeader;
+import org.apache.atlas.model.instance.AtlasObjectId;
+import org.apache.atlas.model.instance.AtlasRelatedObjectId;
+import org.apache.atlas.model.instance.EntityMutationResponse;
+import org.apache.atlas.model.typedef.AtlasTypesDef;
+import org.apache.atlas.repository.graph.AtlasGraphProvider;
+import org.apache.atlas.repository.graph.GraphBackedSearchIndexer;
+import org.apache.atlas.repository.store.bootstrap.AtlasTypeDefStoreInitializer;
+import org.apache.atlas.repository.store.graph.AtlasEntityStore;
+import org.apache.atlas.repository.store.graph.AtlasRelationshipStore;
+import org.apache.atlas.store.AtlasTypeDefStore;
+import org.apache.atlas.type.AtlasEntityType;
+import org.apache.atlas.type.AtlasTypeRegistry;
+import org.apache.commons.collections.CollectionUtils;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+
+import javax.inject.Inject;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.apache.atlas.TestRelationshipUtilsV2.EMPLOYEE_TYPE;
+import static org.apache.atlas.TestRelationshipUtilsV2.getDepartmentEmployeeInstances;
+import static org.apache.atlas.TestRelationshipUtilsV2.getDepartmentEmployeeTypes;
+import static org.apache.atlas.TestRelationshipUtilsV2.getInverseReferenceTestTypes;
+import static org.apache.atlas.TestUtilsV2.NAME;
+import static org.apache.atlas.type.AtlasTypeUtil.getAtlasObjectId;
+import static org.mockito.Mockito.mock;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+@Guice(modules = TestModules.TestOnlyModule.class)
+public abstract class AtlasRelationshipStoreV1Test {
+
+    @Inject
+    AtlasTypeRegistry typeRegistry;
+
+    @Inject
+    AtlasTypeDefStore typeDefStore;
+
+    @Inject
+    DeleteHandlerV1   deleteHandler;
+
+    @Inject
+    EntityGraphMapper graphMapper;
+
+    AtlasEntityStore          entityStore;
+    AtlasRelationshipStore    relationshipStore;
+    AtlasEntityChangeNotifier mockChangeNotifier = mock(AtlasEntityChangeNotifier.class);
+
+    protected Map<String, AtlasObjectId> employeeNameIdMap = new HashMap<>();
+
+    @BeforeClass
+    public void setUp() throws Exception {
+        new GraphBackedSearchIndexer(typeRegistry);
+
+        // create employee relationship types
+        AtlasTypesDef employeeTypes = getDepartmentEmployeeTypes();
+        typeDefStore.createTypesDef(employeeTypes);
+
+        AtlasEntitiesWithExtInfo employeeInstances = getDepartmentEmployeeInstances();
+        EntityMutationResponse response = entityStore.createOrUpdate(new AtlasEntityStream(employeeInstances), false);
+
+        for (AtlasEntityHeader entityHeader : response.getCreatedEntities()) {
+            employeeNameIdMap.put((String) entityHeader.getAttribute(NAME), getAtlasObjectId(entityHeader));
+        }
+
+        init();
+        AtlasTypesDef typesDef = getInverseReferenceTestTypes();
+
+        AtlasTypesDef typesToCreate = AtlasTypeDefStoreInitializer.getTypesToCreate(typesDef, typeRegistry);
+
+        if (!typesToCreate.isEmpty()) {
+            typeDefStore.createTypesDef(typesToCreate);
+        }
+    }
+
+    @BeforeTest
+    public void init() throws Exception {
+        entityStore       = new AtlasEntityStoreV1(deleteHandler, typeRegistry, mockChangeNotifier, graphMapper);
+        relationshipStore = new AtlasRelationshipStoreV1(typeRegistry);
+
+        RequestContextV1.clear();
+        RequestContextV1.get().setUser(TestUtilsV2.TEST_USER);
+    }
+
+    @AfterClass
+    public void clear() {
+        AtlasGraphProvider.cleanup();
+    }
+
+    @Test
+    public void testDepartmentEmployeeEntitiesUsingRelationship() throws Exception  {
+        AtlasObjectId hrId     = employeeNameIdMap.get("hr");
+        AtlasObjectId maxId    = employeeNameIdMap.get("Max");
+        AtlasObjectId johnId   = employeeNameIdMap.get("John");
+        AtlasObjectId juliusId = employeeNameIdMap.get("Julius");
+        AtlasObjectId janeId   = employeeNameIdMap.get("Jane");
+        AtlasObjectId mikeId   = employeeNameIdMap.get("Mike");
+
+        AtlasEntity hrDept = getEntityFromStore(hrId.getGuid());
+        AtlasEntity max    = getEntityFromStore(maxId.getGuid());
+        AtlasEntity john   = getEntityFromStore(johnId.getGuid());
+        AtlasEntity julius = getEntityFromStore(juliusId.getGuid());
+        AtlasEntity jane   = getEntityFromStore(janeId.getGuid());
+        AtlasEntity mike   = getEntityFromStore(mikeId.getGuid());
+
+        // Department relationship attributes
+        List<AtlasObjectId> deptEmployees = toAtlasObjectIds(hrDept.getRelationshipAttribute("employees"));
+        assertNotNull(deptEmployees);
+        assertEquals(deptEmployees.size(), 5);
+        assertObjectIdsContains(deptEmployees, maxId);
+        assertObjectIdsContains(deptEmployees, johnId);
+        assertObjectIdsContains(deptEmployees, juliusId);
+        assertObjectIdsContains(deptEmployees, janeId);
+        assertObjectIdsContains(deptEmployees, mikeId);
+
+        // Max employee validation
+        AtlasObjectId maxDepartmentId = toAtlasObjectId(max.getRelationshipAttribute("department"));
+        assertNotNull(maxDepartmentId);
+        assertObjectIdEquals(maxDepartmentId, hrId);
+
+        AtlasObjectId maxManagerId = toAtlasObjectId(max.getRelationshipAttribute("manager"));
+        assertNotNull(maxManagerId);
+        assertObjectIdEquals(maxManagerId, janeId);
+
+        List<AtlasObjectId> maxMentorsId = toAtlasObjectIds(max.getRelationshipAttribute("mentors"));
+        assertNotNull(maxMentorsId);
+        assertEquals(maxMentorsId.size(), 1);
+        assertObjectIdEquals(maxMentorsId.get(0), juliusId);
+
+        List<AtlasObjectId> maxMenteesId = toAtlasObjectIds(max.getRelationshipAttribute("mentees"));
+        assertNotNull(maxMenteesId);
+        assertEquals(maxMenteesId.size(), 1);
+        assertObjectIdEquals(maxMenteesId.get(0), johnId);
+
+        List<AtlasObjectId> maxFriendsIds = toAtlasObjectIds(max.getRelationshipAttribute("friends"));
+        assertNotNull(maxFriendsIds);
+        assertEquals(maxFriendsIds.size(), 2);
+        assertObjectIdsContains(maxFriendsIds, mikeId);
+        assertObjectIdsContains(maxFriendsIds, johnId);
+
+        // John Employee validation
+        AtlasObjectId johnDepartmentId = toAtlasObjectId(john.getRelationshipAttribute("department"));
+        assertNotNull(johnDepartmentId);
+        assertObjectIdEquals(johnDepartmentId, hrId);
+
+        AtlasObjectId johnManagerId = toAtlasObjectId(john.getRelationshipAttribute("manager"));
+        assertNotNull(johnManagerId);
+        assertObjectIdEquals(johnManagerId, janeId);
+
+        List<AtlasObjectId> johnMentorIds = toAtlasObjectIds(john.getRelationshipAttribute("mentors"));
+        assertNotNull(johnMentorIds);
+        assertEquals(johnMentorIds.size(), 2);
+        assertObjectIdsContains(johnMentorIds, maxId);
+        assertObjectIdsContains(johnMentorIds, juliusId);
+
+        List<AtlasObjectId> johnMenteesId = toAtlasObjectIds(john.getRelationshipAttribute("mentees"));
+        assertEmpty(johnMenteesId);
+
+        List<AtlasObjectId> johnFriendsIds = toAtlasObjectIds(john.getRelationshipAttribute("friends"));
+        assertNotNull(johnFriendsIds);
+        assertEquals(johnFriendsIds.size(), 2);
+        assertObjectIdsContains(johnFriendsIds, mikeId);
+        assertObjectIdsContains(johnFriendsIds, maxId);
+
+        // Mike Employee validation
+        AtlasObjectId mikeDepartmentId = toAtlasObjectId(mike.getRelationshipAttribute("department"));
+        assertNotNull(mikeDepartmentId);
+        assertObjectIdEquals(mikeDepartmentId, hrId);
+
+        AtlasObjectId mikeManagerId = toAtlasObjectId(mike.getRelationshipAttribute("manager"));
+        assertNotNull(mikeManagerId);
+        assertObjectIdEquals(mikeManagerId, juliusId);
+
+        List<AtlasObjectId> mikeMentorIds = toAtlasObjectIds(mike.getRelationshipAttribute("mentors"));
+        assertEmpty(mikeMentorIds);
+
+        List<AtlasObjectId> mikeMenteesId = toAtlasObjectIds(mike.getRelationshipAttribute("mentees"));
+        assertEmpty(mikeMenteesId);
+
+        List<AtlasObjectId> mikeFriendsIds = toAtlasObjectIds(mike.getRelationshipAttribute("friends"));
+        assertNotNull(mikeFriendsIds);
+        assertEquals(mikeFriendsIds.size(), 2);
+        assertObjectIdsContains(mikeFriendsIds, maxId);
+        assertObjectIdsContains(mikeFriendsIds, johnId);
+
+        // Jane Manager validation
+        AtlasObjectId janeDepartmentId = toAtlasObjectId(jane.getRelationshipAttribute("department"));
+        assertNotNull(janeDepartmentId);
+        assertObjectIdEquals(janeDepartmentId, hrId);
+
+        AtlasObjectId janeManagerId = toAtlasObjectId(jane.getRelationshipAttribute("manager"));
+        assertNull(janeManagerId);
+
+        List<AtlasObjectId> janeMentorIds = toAtlasObjectIds(jane.getRelationshipAttribute("mentors"));
+        assertEmpty(janeMentorIds);
+
+        List<AtlasObjectId> janeMenteesId = toAtlasObjectIds(jane.getRelationshipAttribute("mentees"));
+        assertEmpty(janeMenteesId);
+
+        List<AtlasObjectId> janeSubordinateIds = toAtlasObjectIds(jane.getRelationshipAttribute("subordinates"));
+        assertNotNull(janeSubordinateIds);
+        assertEquals(janeSubordinateIds.size(), 2);
+        assertObjectIdsContains(janeSubordinateIds, maxId);
+        assertObjectIdsContains(janeSubordinateIds, johnId);
+
+        List<AtlasObjectId> janeFriendsIds = toAtlasObjectIds(jane.getRelationshipAttribute("friends"));
+        assertEmpty(janeFriendsIds);
+
+        AtlasObjectId janeSiblingId = toAtlasObjectId(jane.getRelationshipAttribute("sibling"));
+        assertNotNull(janeSiblingId);
+        assertObjectIdEquals(janeSiblingId, juliusId);
+
+        // Julius Manager validation
+        AtlasObjectId juliusDepartmentId = toAtlasObjectId(julius.getRelationshipAttribute("department"));
+        assertNotNull(juliusDepartmentId);
+        assertObjectIdEquals(juliusDepartmentId, hrId);
+
+        AtlasObjectId juliusManagerId = toAtlasObjectId(julius.getRelationshipAttribute("manager"));
+        assertNull(juliusManagerId);
+
+        List<AtlasObjectId> juliusMentorIds = toAtlasObjectIds(julius.getRelationshipAttribute("mentors"));
+        assertEmpty(juliusMentorIds);
+
+        List<AtlasObjectId> juliusMenteesId = toAtlasObjectIds(julius.getRelationshipAttribute("mentees"));
+        assertNotNull(juliusMenteesId);
+        assertEquals(juliusMenteesId.size(), 2);
+        assertObjectIdsContains(juliusMenteesId, maxId);
+        assertObjectIdsContains(juliusMenteesId, johnId);
+
+        List<AtlasObjectId> juliusSubordinateIds = toAtlasObjectIds(julius.getRelationshipAttribute("subordinates"));
+        assertNotNull(juliusSubordinateIds);
+        assertEquals(juliusSubordinateIds.size(), 1);
+        assertObjectIdsContains(juliusSubordinateIds, mikeId);
+
+        List<AtlasObjectId> juliusFriendsIds = toAtlasObjectIds(julius.getRelationshipAttribute("friends"));
+        assertEmpty(juliusFriendsIds);
+
+        AtlasObjectId juliusSiblingId = toAtlasObjectId(julius.getRelationshipAttribute("sibling"));
+        assertNotNull(juliusSiblingId);
+        assertObjectIdEquals(juliusSiblingId, janeId);
+    }
+
+    // Seeing intermittent failures with janus profile, disabling it until its fixed.
+    @Test(enabled = false)
+    public void testRelationshipAttributeUpdate_NonComposite_OneToMany() throws Exception {
+        AtlasObjectId maxId    = employeeNameIdMap.get("Max");
+        AtlasObjectId juliusId = employeeNameIdMap.get("Julius");
+        AtlasObjectId janeId   = employeeNameIdMap.get("Jane");
+        AtlasObjectId mikeId   = employeeNameIdMap.get("Mike");
+        AtlasObjectId johnId   = employeeNameIdMap.get("John");
+
+        // Change Max's Employee.manager reference to Julius and apply the change as a partial update.
+        // This should also update Julius to add Max to the inverse Manager.subordinates reference.
+        AtlasEntity maxEntityForUpdate = new AtlasEntity(EMPLOYEE_TYPE);
+        maxEntityForUpdate.setRelationshipAttribute("manager", juliusId);
+
+        AtlasEntityType        employeeType   = typeRegistry.getEntityTypeByName(EMPLOYEE_TYPE);
+        Map<String, Object>    uniqAttributes = Collections.<String, Object>singletonMap("name", "Max");
+        EntityMutationResponse updateResponse = entityStore.updateByUniqueAttributes(employeeType, uniqAttributes , new AtlasEntityWithExtInfo(maxEntityForUpdate));
+
+        List<AtlasEntityHeader> partialUpdatedEntities = updateResponse.getPartialUpdatedEntities();
+        assertEquals(partialUpdatedEntities.size(), 3);
+        // 3 entities should have been updated:
+        // * Max to change the Employee.manager reference
+        // * Julius to add Max to Manager.subordinates
+        // * Jane to remove Max from Manager.subordinates
+
+        AtlasEntitiesWithExtInfo updatedEntities = entityStore.getByIds(ImmutableList.of(maxId.getGuid(), juliusId.getGuid(), janeId.getGuid()));
+
+        // Max's manager updated as Julius
+        AtlasEntity maxEntity = updatedEntities.getEntity(maxId.getGuid());
+        verifyRelationshipAttributeValue(maxEntity, "manager", juliusId.getGuid());
+
+        // Max added to the subordinate list of Julius, existing subordinate is Mike
+        AtlasEntity juliusEntity = updatedEntities.getEntity(juliusId.getGuid());
+        verifyRelationshipAttributeList(juliusEntity, "subordinates", ImmutableList.of(maxId, mikeId));
+
+        // Max removed from the subordinate list of Julius
+        AtlasEntity janeEntity = updatedEntities.getEntity(janeId.getGuid());
+
+        // Jane's subordinates list includes John and Max for soft delete
+        // Jane's subordinates list includes only John for hard delete
+        verifyRelationshipAttributeUpdate_NonComposite_OneToMany(janeEntity);
+
+        // Remove Mike from Max's friends list
+        // Max's current friends: [Mike, John]
+        // Max's updated friends: [Julius, John]
+        maxEntityForUpdate = new AtlasEntity(EMPLOYEE_TYPE);
+        maxEntityForUpdate.setRelationshipAttribute("friends", ImmutableList.of(johnId, juliusId));
+
+        init();
+        updateResponse = entityStore.updateByUniqueAttributes(employeeType, uniqAttributes , new AtlasEntityWithExtInfo(maxEntityForUpdate));
+
+        partialUpdatedEntities = updateResponse.getPartialUpdatedEntities();
+        assertEquals(partialUpdatedEntities.size(), 3);
+        // 3 entities should have been updated:
+        // * Max added Julius and removed Mike from Employee.friends
+        // * Mike removed Max from Employee.friends
+        // * Julius added Max in Employee.friends
+
+        updatedEntities = entityStore.getByIds(ImmutableList.of(maxId.getGuid(), mikeId.getGuid(), johnId.getGuid(), juliusId.getGuid()));
+
+        maxEntity    = updatedEntities.getEntity(maxId.getGuid());
+        juliusEntity = updatedEntities.getEntity(juliusId.getGuid());
+        AtlasEntity mikeEntity = updatedEntities.getEntity(mikeId.getGuid());
+        AtlasEntity johnEntity = updatedEntities.getEntity(johnId.getGuid());
+
+        verifyRelationshipAttributeUpdate_ManyToMany_Friends(maxEntity, juliusEntity, mikeEntity, johnEntity);
+
+        // Remove Julius from Jane's sibling and add Mike as new sibling
+        AtlasEntity juliusEntityForUpdate = new AtlasEntity(EMPLOYEE_TYPE);
+        juliusEntityForUpdate.setRelationshipAttribute("sibling", mikeId);
+
+        init();
+        updateResponse = entityStore.updateByUniqueAttributes(employeeType, Collections.<String, Object>singletonMap("name", "Julius") , new AtlasEntityWithExtInfo(juliusEntityForUpdate));
+        partialUpdatedEntities = updateResponse.getPartialUpdatedEntities();
+        assertEquals(partialUpdatedEntities.size(), 3);
+
+        updatedEntities = entityStore.getByIds(ImmutableList.of(juliusId.getGuid(), janeId.getGuid(), mikeId.getGuid()));
+
+        juliusEntity = updatedEntities.getEntity(juliusId.getGuid());
+        janeEntity   = updatedEntities.getEntity(janeId.getGuid());
+        mikeEntity   = updatedEntities.getEntity(mikeId.getGuid());
+
+        verifyRelationshipAttributeUpdate_OneToOne_Sibling(juliusEntity, janeEntity, mikeEntity);
+    }
+
+    @Test
+    public void testRelationshipAttributeUpdate_NonComposite_ManyToOne() throws Exception {
+        AtlasEntity a1 = new AtlasEntity("A");
+        a1.setAttribute(NAME, "a1_name");
+
+        AtlasEntity a2 = new AtlasEntity("A");
+        a2.setAttribute(NAME, "a2_name");
+
+        AtlasEntity a3 = new AtlasEntity("A");
+        a3.setAttribute(NAME, "a3_name");
+
+        AtlasEntity b = new AtlasEntity("B");
+        b.setAttribute(NAME, "b_name");
+
+        AtlasEntitiesWithExtInfo entitiesWithExtInfo = new AtlasEntitiesWithExtInfo();
+        entitiesWithExtInfo.addEntity(a1);
+        entitiesWithExtInfo.addEntity(a2);
+        entitiesWithExtInfo.addEntity(a3);
+        entitiesWithExtInfo.addEntity(b);
+        entityStore.createOrUpdate(new AtlasEntityStream(entitiesWithExtInfo) , false);
+
+        AtlasEntity bPartialUpdate = new AtlasEntity("B");
+        bPartialUpdate.setRelationshipAttribute("manyA", ImmutableList.of(getAtlasObjectId(a1), getAtlasObjectId(a2)));
+
+        init();
+        EntityMutationResponse response = entityStore.updateByUniqueAttributes(typeRegistry.getEntityTypeByName("B"),
+                                                                               Collections.singletonMap(NAME, b.getAttribute(NAME)),
+                                                                               new AtlasEntityWithExtInfo(bPartialUpdate));
+        // Verify 3 entities were updated:
+        // * set b.manyA reference to a1 and a2
+        // * set inverse a1.oneB reference to b
+        // * set inverse a2.oneB reference to b
+        assertEquals(response.getPartialUpdatedEntities().size(), 3);
+        AtlasEntitiesWithExtInfo updatedEntities = entityStore.getByIds(ImmutableList.of(a1.getGuid(), a2.getGuid(), b.getGuid()));
+
+        AtlasEntity a1Entity = updatedEntities.getEntity(a1.getGuid());
+        verifyRelationshipAttributeValue(a1Entity, "oneB", b.getGuid());
+
+        AtlasEntity a2Entity = updatedEntities.getEntity(a2.getGuid());
+        verifyRelationshipAttributeValue(a2Entity, "oneB", b.getGuid());
+
+        AtlasEntity bEntity = updatedEntities.getEntity(b.getGuid());
+        verifyRelationshipAttributeList(bEntity, "manyA", ImmutableList.of(getAtlasObjectId(a1), getAtlasObjectId(a2)));
+
+
+        bPartialUpdate.setRelationshipAttribute("manyA", ImmutableList.of(getAtlasObjectId(a3)));
+        init();
+        response = entityStore.updateByUniqueAttributes(typeRegistry.getEntityTypeByName("B"),
+                                                        Collections.singletonMap(NAME, b.getAttribute(NAME)),
+                                                        new AtlasEntityWithExtInfo(bPartialUpdate));
+        // Verify 4 entities were updated:
+        // * set b.manyA reference to a3
+        // * set inverse a3.oneB reference to b
+        // * disconnect inverse a1.oneB reference to b
+        // * disconnect inverse a2.oneB reference to b
+        assertEquals(response.getPartialUpdatedEntities().size(), 4);
+        init();
+
+        updatedEntities = entityStore.getByIds(ImmutableList.of(a1.getGuid(), a2.getGuid(), a3.getGuid(), b.getGuid()));
+        a1Entity        = updatedEntities.getEntity(a1.getGuid());
+        a2Entity        = updatedEntities.getEntity(a2.getGuid());
+        bEntity         = updatedEntities.getEntity(b.getGuid());
+
+        AtlasEntity a3Entity = updatedEntities.getEntity(a3.getGuid());
+        verifyRelationshipAttributeValue(a3Entity, "oneB", b.getGuid());
+
+        verifyRelationshipAttributeUpdate_NonComposite_ManyToOne(a1Entity, a2Entity, a3Entity, bEntity);
+    }
+
+    @Test
+    public void testRelationshipAttributeUpdate_NonComposite_OneToOne() throws Exception {
+        AtlasEntity a1 = new AtlasEntity("A");
+        a1.setAttribute(NAME, "a1_name");
+
+        AtlasEntity a2 = new AtlasEntity("A");
+        a2.setAttribute(NAME, "a2_name");
+
+        AtlasEntity b = new AtlasEntity("B");
+        b.setAttribute(NAME, "b_name");
+
+        AtlasEntitiesWithExtInfo entitiesWithExtInfo = new AtlasEntitiesWithExtInfo();
+        entitiesWithExtInfo.addEntity(a1);
+        entitiesWithExtInfo.addEntity(a2);
+        entitiesWithExtInfo.addEntity(b);
+
+        EntityMutationResponse response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesWithExtInfo) , false);
+
+        AtlasEntity partialUpdateB = new AtlasEntity("B");
+        partialUpdateB.setRelationshipAttribute("a", getAtlasObjectId(a1));
+
+        init();
+        AtlasEntityType bType = typeRegistry.getEntityTypeByName("B");
+
+        response = entityStore.updateByUniqueAttributes(bType, Collections.singletonMap(NAME, b.getAttribute(NAME)), new AtlasEntityWithExtInfo(partialUpdateB));
+        List<AtlasEntityHeader> partialUpdatedEntitiesHeader = response.getPartialUpdatedEntities();
+        // Verify 2 entities were updated:
+        // * set b.a reference to a1
+        // * set inverse a1.b reference to b
+        assertEquals(partialUpdatedEntitiesHeader.size(), 2);
+        AtlasEntitiesWithExtInfo partialUpdatedEntities = entityStore.getByIds(ImmutableList.of(a1.getGuid(), b.getGuid()));
+
+        AtlasEntity a1Entity = partialUpdatedEntities.getEntity(a1.getGuid());
+        verifyRelationshipAttributeValue(a1Entity, "b", b.getGuid());
+
+        AtlasEntity bEntity = partialUpdatedEntities.getEntity(b.getGuid());
+        verifyRelationshipAttributeValue(bEntity, "a", a1.getGuid());
+
+        init();
+
+        // Update b.a to reference a2.
+        partialUpdateB.setRelationshipAttribute("a", getAtlasObjectId(a2));
+        response = entityStore.updateByUniqueAttributes(bType, Collections.<String, Object>singletonMap(NAME, b.getAttribute(NAME)), new AtlasEntityWithExtInfo(partialUpdateB));
+        partialUpdatedEntitiesHeader = response.getPartialUpdatedEntities();
+        // Verify 3 entities were updated:
+        // * set b.a reference to a2
+        // * set a2.b reference to b
+        // * disconnect a1.b reference
+        assertEquals(partialUpdatedEntitiesHeader.size(), 3);
+        partialUpdatedEntities = entityStore.getByIds(ImmutableList.of(a1.getGuid(), a2.getGuid(), b.getGuid()));
+
+        bEntity = partialUpdatedEntities.getEntity(b.getGuid());
+        verifyRelationshipAttributeValue(bEntity, "a", a2.getGuid());
+
+        AtlasEntity a2Entity = partialUpdatedEntities.getEntity(a2.getGuid());
+        verifyRelationshipAttributeValue(a2Entity, "b", b.getGuid());
+
+        a1Entity = partialUpdatedEntities.getEntity(a1.getGuid());
+        verifyRelationshipAttributeUpdate_NonComposite_OneToOne(a1Entity, bEntity);
+    }
+
+    @Test
+    public void testRelationshipAttributeUpdate_NonComposite_ManyToMany() throws Exception {
+        AtlasEntity a1 = new AtlasEntity("A");
+        a1.setAttribute(NAME, "a1_name");
+
+        AtlasEntity a2 = new AtlasEntity("A");
+        a2.setAttribute(NAME, "a2_name");
+
+        AtlasEntity a3 = new AtlasEntity("A");
+        a3.setAttribute(NAME, "a3_name");
+
+        AtlasEntity b1 = new AtlasEntity("B");
+        b1.setAttribute(NAME, "b1_name");
+
+        AtlasEntity b2 = new AtlasEntity("B");
+        b2.setAttribute(NAME, "b2_name");
+
+        AtlasEntitiesWithExtInfo entitiesWithExtInfo = new AtlasEntitiesWithExtInfo();
+        entitiesWithExtInfo.addEntity(a1);
+        entitiesWithExtInfo.addEntity(a2);
+        entitiesWithExtInfo.addEntity(a3);
+        entitiesWithExtInfo.addEntity(b1);
+        entitiesWithExtInfo.addEntity(b2);
+        entityStore.createOrUpdate(new AtlasEntityStream(entitiesWithExtInfo) , false);
+
+        AtlasEntity b1PartialUpdate = new AtlasEntity("B");
+        b1PartialUpdate.setRelationshipAttribute("manyToManyA", ImmutableList.of(getAtlasObjectId(a1), getAtlasObjectId(a2)));
+
+        init();
+        EntityMutationResponse response = entityStore.updateByUniqueAttributes(typeRegistry.getEntityTypeByName("B"),
+                                                                               Collections.singletonMap(NAME, b1.getAttribute(NAME)),
+                                                                               new AtlasEntityWithExtInfo(b1PartialUpdate));
+
+        List<AtlasEntityHeader> updatedEntityHeaders = response.getPartialUpdatedEntities();
+        assertEquals(updatedEntityHeaders.size(), 3);
+
+        AtlasEntitiesWithExtInfo updatedEntities = entityStore.getByIds(ImmutableList.of(a1.getGuid(), a2.getGuid(), b1.getGuid()));
+
+        AtlasEntity b1Entity = updatedEntities.getEntity(b1.getGuid());
+        verifyRelationshipAttributeList(b1Entity, "manyToManyA", ImmutableList.of(getAtlasObjectId(a1), getAtlasObjectId(a2)));
+
+        AtlasEntity a1Entity = updatedEntities.getEntity(a1.getGuid());
+        verifyRelationshipAttributeList(a1Entity, "manyB", ImmutableList.of(getAtlasObjectId(b1)));
+
+        AtlasEntity a2Entity = updatedEntities.getEntity(a2.getGuid());
+        verifyRelationshipAttributeList(a2Entity, "manyB", ImmutableList.of(getAtlasObjectId(b1)));
+    }
+
+    protected abstract void verifyRelationshipAttributeUpdate_NonComposite_OneToOne(AtlasEntity a1, AtlasEntity b);
+
+    protected abstract void verifyRelationshipAttributeUpdate_NonComposite_OneToMany(AtlasEntity entity) throws Exception;
+
+    protected abstract void verifyRelationshipAttributeUpdate_NonComposite_ManyToOne(AtlasEntity a1, AtlasEntity a2, AtlasEntity a3, AtlasEntity b);
+
+    protected abstract void verifyRelationshipAttributeUpdate_ManyToMany_Friends(AtlasEntity e1, AtlasEntity e2, AtlasEntity e3, AtlasEntity e4) throws Exception;
+
+    protected abstract void verifyRelationshipAttributeUpdate_OneToOne_Sibling(AtlasEntity e1, AtlasEntity e2, AtlasEntity e3) throws Exception;
+
+    protected static void assertObjectIdsContains(List<AtlasObjectId> objectIds, AtlasObjectId objectId) {
+        assertTrue(CollectionUtils.isNotEmpty(objectIds));
+        assertTrue(objectIds.contains(objectId));
+    }
+
+    protected static void assertObjectIdEquals(AtlasObjectId objId1, AtlasObjectId objId2) {
+        assertTrue(objId1.equals(objId2));
+    }
+
+    private static void assertEmpty(List collection) {
+        assertTrue(collection != null && collection.isEmpty());
+    }
+
+    protected static List<AtlasObjectId> toAtlasObjectIds(Object object) {
+        List<AtlasObjectId> ret = new ArrayList<>();
+
+        if (object instanceof List) {
+            List<?> objectIds = (List) object;
+
+            if (CollectionUtils.isNotEmpty(objectIds)) {
+                for (Object obj : objectIds) {
+                    if (obj instanceof AtlasRelatedObjectId) {
+                        AtlasRelatedObjectId relatedObjectId = (AtlasRelatedObjectId) obj;
+                        ret.add(new AtlasObjectId(relatedObjectId.getGuid(), relatedObjectId.getTypeName(), relatedObjectId.getUniqueAttributes()));
+                    }
+                }
+            }
+        }
+
+        return ret;
+    }
+
+    protected static AtlasObjectId toAtlasObjectId(Object object) {
+        if (object instanceof AtlasRelatedObjectId) {
+            AtlasRelatedObjectId relatedObjectId = (AtlasRelatedObjectId) object;
+            return new AtlasObjectId(relatedObjectId.getGuid(), relatedObjectId.getTypeName(), relatedObjectId.getUniqueAttributes());
+        }
+
+        return null;
+    }
+
+    private AtlasEntity getEntityFromStore(String guid) throws AtlasBaseException {
+        AtlasEntityWithExtInfo entity = guid != null ? entityStore.getById(guid) : null;
+
+        return entity != null ? entity.getEntity() : null;
+    }
+
+    protected static void verifyRelationshipAttributeList(AtlasEntity entity, String relationshipAttrName, List<AtlasObjectId> expectedValues) {
+        Object refValue = entity.getRelationshipAttribute(relationshipAttrName);
+        assertTrue(refValue instanceof List);
+
+        List<AtlasObjectId> refList = toAtlasObjectIds(refValue);
+        assertEquals(refList.size(), expectedValues.size());
+
+        if (expectedValues.size() > 0) {
+            assertTrue(refList.containsAll(expectedValues));
+        }
+    }
+
+    protected static void verifyRelationshipAttributeValue(AtlasEntity entity, String relationshipAttrName, String expectedGuid) {
+        Object refValue = entity.getRelationshipAttribute(relationshipAttrName);
+        if (expectedGuid == null) {
+            assertNull(refValue);
+        }
+        else {
+            assertTrue(refValue instanceof AtlasObjectId);
+            AtlasObjectId referencedObjectId = (AtlasObjectId) refValue;
+            assertEquals(referencedObjectId.getGuid(), expectedGuid);
+        }
+    }
+}
\ No newline at end of file
diff --git a/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/InverseReferenceUpdateHardDeleteV1Test.java b/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/InverseReferenceUpdateHardDeleteV1Test.java
new file mode 100644
index 0000000..d54adeb
--- /dev/null
+++ b/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/InverseReferenceUpdateHardDeleteV1Test.java
@@ -0,0 +1,75 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.repository.store.graph.v1;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.atlas.TestModules;
+import org.apache.atlas.model.instance.AtlasEntity;
+import org.apache.atlas.model.instance.AtlasObjectId;
+import org.apache.atlas.type.AtlasTypeUtil;
+import org.testng.annotations.Guice;
+
+import java.util.Map;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+/**
+ * Inverse reference update test with {@link HardDeleteHandlerV1}
+ */
+@Guice(modules = TestModules.HardDeleteModule.class)
+public class InverseReferenceUpdateHardDeleteV1Test extends InverseReferenceUpdateV1Test {
+
+    @Override
+    protected void verify_testInverseReferenceAutoUpdate_NonComposite_OneToMany(AtlasEntity jane) throws Exception {
+
+        // Max should have been removed from the subordinates list, leaving only John.
+        verifyReferenceList(jane, "subordinates", ImmutableList.of(nameIdMap.get("John")));
+    }
+
+    @Override
+    protected void verify_testInverseReferenceAutoUpdate_NonCompositeManyToOne(AtlasEntity a1, AtlasEntity a2, AtlasEntity a3, AtlasEntity b) {
+
+        verifyReferenceValue(a1, "oneB", null);
+
+        verifyReferenceValue(a2, "oneB", null);
+
+        verifyReferenceList(b, "manyA", ImmutableList.of(AtlasTypeUtil.getAtlasObjectId(a3)));
+    }
+
+    @Override
+    protected void verify_testInverseReferenceAutoUpdate_NonComposite_OneToOne(AtlasEntity a1, AtlasEntity b) {
+
+        verifyReferenceValue(a1, "b", null);
+    }
+
+    @Override
+    protected void verify_testInverseReferenceAutoUpdate_Map(AtlasEntity a1, AtlasEntity b1,
+        AtlasEntity b2, AtlasEntity b3) {
+
+        Object value = a1.getAttribute("mapToB");
+        assertTrue(value instanceof Map);
+        Map<String, AtlasObjectId> refMap = (Map<String, AtlasObjectId>) value;
+        assertEquals(refMap.size(), 1);
+        AtlasObjectId referencedEntityId = refMap.get("b3");
+        assertEquals(referencedEntityId, AtlasTypeUtil.getAtlasObjectId(b3));
+        verifyReferenceValue(b1, "mappedFromA", null);
+        verifyReferenceValue(b2, "mappedFromA", null);
+    }
+
+}
diff --git a/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/InverseReferenceUpdateSoftDeleteV1Test.java b/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/InverseReferenceUpdateSoftDeleteV1Test.java
new file mode 100644
index 0000000..884ab54
--- /dev/null
+++ b/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/InverseReferenceUpdateSoftDeleteV1Test.java
@@ -0,0 +1,78 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.repository.store.graph.v1;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.atlas.TestModules;
+import org.apache.atlas.model.instance.AtlasEntity;
+import org.apache.atlas.model.instance.AtlasObjectId;
+import org.apache.atlas.type.AtlasTypeUtil;
+import org.testng.annotations.Guice;
+
+import java.util.Map;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+
+/**
+ * Inverse reference update test with {@link SoftDeleteHandlerV1}
+ */
+@Guice(modules = TestModules.SoftDeleteModule.class)
+public class InverseReferenceUpdateSoftDeleteV1Test extends InverseReferenceUpdateV1Test {
+
+    @Override
+    protected void verify_testInverseReferenceAutoUpdate_NonComposite_OneToMany(AtlasEntity jane)
+        throws Exception {
+
+        // Max is still in the subordinates list, as the edge still exists with state DELETED
+        verifyReferenceList(jane, "subordinates", ImmutableList.of(nameIdMap.get("John"), nameIdMap.get("Max")));
+    }
+
+    @Override
+    protected void verify_testInverseReferenceAutoUpdate_NonCompositeManyToOne(AtlasEntity a1,
+        AtlasEntity a2, AtlasEntity a3, AtlasEntity b) {
+
+        verifyReferenceValue(a1, "oneB", b.getGuid());
+
+        verifyReferenceValue(a2, "oneB", b.getGuid());
+
+        verifyReferenceList(b, "manyA", ImmutableList.of(AtlasTypeUtil.getAtlasObjectId(a1), AtlasTypeUtil.getAtlasObjectId(a2), AtlasTypeUtil.getAtlasObjectId(a3)));
+    }
+
+    @Override
+    protected void verify_testInverseReferenceAutoUpdate_NonComposite_OneToOne(AtlasEntity a1, AtlasEntity b) {
+
+        verifyReferenceValue(a1, "b", b.getGuid());
+    }
+
+    @Override
+    protected void verify_testInverseReferenceAutoUpdate_Map(AtlasEntity a1, AtlasEntity b1,
+        AtlasEntity b2, AtlasEntity b3) {
+
+        Object value = a1.getAttribute("mapToB");
+        assertTrue(value instanceof Map);
+        Map<String, AtlasObjectId> refMap = (Map<String, AtlasObjectId>) value;
+        assertEquals(refMap.size(), 3);
+        AtlasObjectId referencedEntityId = refMap.get("b3");
+        assertEquals(referencedEntityId, AtlasTypeUtil.getAtlasObjectId(b3));
+        verifyReferenceValue(b1, "mappedFromA", a1.getGuid());
+        verifyReferenceValue(b2, "mappedFromA", a1.getGuid());
+    }
+
+}
diff --git a/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/InverseReferenceUpdateV1Test.java b/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/InverseReferenceUpdateV1Test.java
new file mode 100644
index 0000000..2c21638
--- /dev/null
+++ b/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/InverseReferenceUpdateV1Test.java
@@ -0,0 +1,374 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.repository.store.graph.v1;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.apache.atlas.RequestContextV1;
+import org.apache.atlas.TestUtilsV2;
+import org.apache.atlas.model.instance.AtlasEntity;
+import org.apache.atlas.model.instance.AtlasEntity.AtlasEntitiesWithExtInfo;
+import org.apache.atlas.model.instance.AtlasEntity.AtlasEntityWithExtInfo;
+import org.apache.atlas.model.instance.AtlasEntityHeader;
+import org.apache.atlas.model.instance.AtlasObjectId;
+import org.apache.atlas.model.instance.EntityMutationResponse;
+import org.apache.atlas.model.typedef.AtlasTypesDef;
+import org.apache.atlas.repository.graph.AtlasGraphProvider;
+import org.apache.atlas.repository.store.bootstrap.AtlasTypeDefStoreInitializer;
+import org.apache.atlas.repository.store.graph.AtlasEntityStore;
+import org.apache.atlas.store.AtlasTypeDefStore;
+import org.apache.atlas.type.AtlasEntityType;
+import org.apache.atlas.type.AtlasTypeRegistry;
+import org.apache.atlas.type.AtlasTypeUtil;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import javax.inject.Inject;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+import static org.apache.atlas.TestUtilsV2.NAME;
+
+/**
+ * Test automatic inverse reference updating in V1 (V2?) code path.
+ *
+ */
+public abstract class InverseReferenceUpdateV1Test {
+    @Inject
+    AtlasTypeRegistry typeRegistry;
+
+    @Inject
+    AtlasTypeDefStore typeDefStore;
+
+    @Inject
+    AtlasEntityStore entityStore;
+
+    private AtlasEntitiesWithExtInfo deptEntity;
+
+    protected Map<String, AtlasObjectId> nameIdMap = new HashMap<>();
+
+    @BeforeClass
+    public void setUp() throws Exception {
+        RequestContextV1.clear();
+        RequestContextV1.get().setUser(TestUtilsV2.TEST_USER);
+
+        AtlasTypesDef[] testTypesDefs = new AtlasTypesDef[] { TestUtilsV2.defineDeptEmployeeTypes(),
+                                                              TestUtilsV2.defineInverseReferenceTestTypes()
+                                                            };
+
+        for (AtlasTypesDef typesDef : testTypesDefs) {
+            AtlasTypesDef typesToCreate = AtlasTypeDefStoreInitializer.getTypesToCreate(typesDef, typeRegistry);
+
+            if (!typesToCreate.isEmpty()) {
+                typeDefStore.createTypesDef(typesToCreate);
+            }
+        }
+
+        deptEntity = TestUtilsV2.createDeptEg2();
+        init();
+        EntityMutationResponse response = entityStore.createOrUpdate(new AtlasEntityStream(deptEntity), false);
+        for (AtlasEntityHeader entityHeader : response.getCreatedEntities()) {
+            nameIdMap.put((String)entityHeader.getAttribute(NAME), AtlasTypeUtil.getAtlasObjectId(entityHeader));
+        }
+    }
+
+    @AfterClass
+    public void clear() {
+        AtlasGraphProvider.cleanup();
+    }
+
+    @BeforeMethod
+    public void init() throws Exception {
+        RequestContextV1.clear();
+        RequestContextV1.get().setUser(TestUtilsV2.TEST_USER);
+    }
+
+    @Test
+    public void testInverseReferenceAutoUpdate_NonComposite_OneToMany() throws Exception {
+        AtlasObjectId juliusId = nameIdMap.get("Julius");
+
+        // Change Max's Employee.manager reference to Julius and apply the change as a partial update.
+        // This should also update Julius to add Max to the inverse Manager.subordinates reference.
+        AtlasEntity maxEntityForUpdate = new AtlasEntity(TestUtilsV2.EMPLOYEE_TYPE);
+        maxEntityForUpdate.setAttribute("manager", juliusId);
+        AtlasEntityType employeeType = typeRegistry.getEntityTypeByName(TestUtilsV2.EMPLOYEE_TYPE);
+        Map<String, Object> uniqAttributes = Collections.<String, Object>singletonMap("name", "Max");
+        EntityMutationResponse updateResponse = entityStore.updateByUniqueAttributes(employeeType, uniqAttributes , new AtlasEntityWithExtInfo(maxEntityForUpdate));
+        List<AtlasEntityHeader> partialUpdatedEntities = updateResponse.getPartialUpdatedEntities();
+        // 3 entities should have been updated:
+        // * Max to change the Employee.manager reference
+        // * Julius to add Max to Manager.subordinates
+        // * Jane to remove Max from Manager.subordinates
+        assertEquals(partialUpdatedEntities.size(), 3);
+
+        AtlasObjectId maxId = nameIdMap.get("Max");
+        String janeGuid = nameIdMap.get("Jane").getGuid();
+        AtlasEntitiesWithExtInfo storedEntities = entityStore.getByIds(ImmutableList.of(maxId.getGuid(), juliusId.getGuid(), janeGuid));
+        AtlasEntity storedEntity = storedEntities.getEntity(maxId.getGuid());
+        verifyReferenceValue(storedEntity, "manager", juliusId.getGuid());
+        storedEntity = storedEntities.getEntity(juliusId.getGuid());
+        verifyReferenceList(storedEntity, "subordinates", ImmutableList.of(maxId));
+        storedEntity = storedEntities.getEntity(janeGuid);
+        verify_testInverseReferenceAutoUpdate_NonComposite_OneToMany(storedEntity);
+    }
+
+    protected abstract void verify_testInverseReferenceAutoUpdate_NonComposite_OneToMany(AtlasEntity jane) throws Exception;
+
+    @Test
+    public void testInverseReferenceAutoUpdate_NonCompositeManyToOne() throws Exception {
+        AtlasEntityType bType = typeRegistry.getEntityTypeByName("B");
+        AtlasEntity a1 = new AtlasEntity("A");
+        a1.setAttribute(NAME, TestUtilsV2.randomString());
+        AtlasEntity a2 = new AtlasEntity("A");
+        a2.setAttribute(NAME, TestUtilsV2.randomString());
+        AtlasEntity a3 = new AtlasEntity("A");
+        a3.setAttribute(NAME, TestUtilsV2.randomString());
+        AtlasEntity b = new AtlasEntity("B");
+
+        b.setAttribute(NAME, TestUtilsV2.randomString());
+        AtlasEntitiesWithExtInfo atlasEntitiesWithExtInfo = new AtlasEntitiesWithExtInfo();
+        atlasEntitiesWithExtInfo.addEntity(a1);
+        atlasEntitiesWithExtInfo.addEntity(a2);
+        atlasEntitiesWithExtInfo.addEntity(a3);
+        atlasEntitiesWithExtInfo.addEntity(b);
+        AtlasEntityStream entityStream = new AtlasEntityStream(atlasEntitiesWithExtInfo);
+        EntityMutationResponse response = entityStore.createOrUpdate(entityStream , false);
+
+        AtlasEntity bForPartialUpdate = new AtlasEntity("B");
+        bForPartialUpdate.setAttribute("manyA", ImmutableList.of(AtlasTypeUtil.getAtlasObjectId(a1), AtlasTypeUtil.getAtlasObjectId(a2)));
+        init();
+        response = entityStore.updateByUniqueAttributes(bType, Collections.<String, Object>singletonMap(NAME, b.getAttribute(NAME)), new AtlasEntityWithExtInfo(bForPartialUpdate));
+        List<AtlasEntityHeader> partialUpdatedEntities = response.getPartialUpdatedEntities();
+        // Verify 3 entities were updated:
+        // * set b.manyA reference to a1 and a2
+        // * set inverse a1.oneB reference to b
+        // * set inverse a2.oneB reference to b
+        assertEquals(partialUpdatedEntities.size(), 3);
+        AtlasEntitiesWithExtInfo storedEntities = entityStore.getByIds(ImmutableList.of(a1.getGuid(), a2.getGuid(), b.getGuid()));
+        AtlasEntity storedEntity = storedEntities.getEntity(a1.getGuid());
+        verifyReferenceValue(storedEntity, "oneB", b.getGuid());
+
+        storedEntity = storedEntities.getEntity(a2.getGuid());
+        verifyReferenceValue(storedEntity, "oneB", b.getGuid());
+
+        storedEntity = storedEntities.getEntity(b.getGuid());
+        verifyReferenceList(storedEntity, "manyA", ImmutableList.of(AtlasTypeUtil.getAtlasObjectId(a1), AtlasTypeUtil.getAtlasObjectId(a2)));
+
+        bForPartialUpdate.setAttribute("manyA", ImmutableList.of(AtlasTypeUtil.getAtlasObjectId(a3)));
+        init();
+        response = entityStore.updateByUniqueAttributes(bType, Collections.<String, Object>singletonMap(NAME, b.getAttribute(NAME)), new AtlasEntityWithExtInfo(bForPartialUpdate));
+        partialUpdatedEntities = response.getPartialUpdatedEntities();
+        // Verify 4 entities were updated:
+        // * set b.manyA reference to a3
+        // * set inverse a3.oneB reference to b
+        // * disconnect inverse a1.oneB reference to b
+        // * disconnect inverse a2.oneB reference to b
+        assertEquals(partialUpdatedEntities.size(), 4);
+
+        init();
+        storedEntities = entityStore.getByIds(ImmutableList.of(a1.getGuid(), a2.getGuid(), a3.getGuid(), b.getGuid()));
+        verifyReferenceValue(storedEntities.getEntity(a3.getGuid()), "oneB", b.getGuid());
+
+        verify_testInverseReferenceAutoUpdate_NonCompositeManyToOne(storedEntities.getEntity(a1.getGuid()), storedEntities.getEntity(a2.getGuid()),
+            storedEntities.getEntity(a3.getGuid()), storedEntities.getEntity(b.getGuid()));
+    }
+
+    protected abstract void verify_testInverseReferenceAutoUpdate_NonCompositeManyToOne(AtlasEntity a1, AtlasEntity a2, AtlasEntity a3, AtlasEntity b);
+
+    @Test
+    public void testInverseReferenceAutoUpdate_NonComposite_OneToOne() throws Exception {
+        AtlasEntityType bType = typeRegistry.getEntityTypeByName("B");
+        AtlasEntity a1 = new AtlasEntity("A");
+        a1.setAttribute(NAME, TestUtilsV2.randomString());
+        AtlasEntity a2 = new AtlasEntity("A");
+        a2.setAttribute(NAME, TestUtilsV2.randomString());
+        AtlasEntity b = new AtlasEntity("B");
+        b.setAttribute(NAME, TestUtilsV2.randomString());
+        AtlasEntitiesWithExtInfo atlasEntitiesWithExtInfo = new AtlasEntitiesWithExtInfo();
+        atlasEntitiesWithExtInfo.addEntity(a1);
+        atlasEntitiesWithExtInfo.addEntity(a2);
+        atlasEntitiesWithExtInfo.addEntity(b);
+        AtlasEntityStream entityStream = new AtlasEntityStream(atlasEntitiesWithExtInfo);
+        EntityMutationResponse response = entityStore.createOrUpdate(entityStream , false);
+
+        AtlasEntity bForPartialUpdate = new AtlasEntity("B");
+        bForPartialUpdate.setAttribute("a", AtlasTypeUtil.getAtlasObjectId(a1));
+        init();
+        response = entityStore.updateByUniqueAttributes(bType, Collections.<String, Object>singletonMap(NAME, b.getAttribute(NAME)), new AtlasEntityWithExtInfo(bForPartialUpdate));
+        List<AtlasEntityHeader> partialUpdatedEntities = response.getPartialUpdatedEntities();
+        // Verify 2 entities were updated:
+        // * set b.a reference to a1
+        // * set inverse a1.b reference to b
+        assertEquals(partialUpdatedEntities.size(), 2);
+        AtlasEntitiesWithExtInfo storedEntities = entityStore.getByIds(ImmutableList.of(a1.getGuid(), b.getGuid()));
+        AtlasEntity storedEntity = storedEntities.getEntity(a1.getGuid());
+        verifyReferenceValue(storedEntity, "b", b.getGuid());
+        storedEntity = storedEntities.getEntity(b.getGuid());
+        verifyReferenceValue(storedEntity, "a", a1.getGuid());
+
+        // Update b.a to reference a2.
+        bForPartialUpdate.setAttribute("a", AtlasTypeUtil.getAtlasObjectId(a2));
+        init();
+        response = entityStore.updateByUniqueAttributes(bType, Collections.<String, Object>singletonMap(NAME, b.getAttribute(NAME)), new AtlasEntityWithExtInfo(bForPartialUpdate));
+        partialUpdatedEntities = response.getPartialUpdatedEntities();
+        // Verify 3 entities were updated:
+        // * set b.a reference to a2
+        // * set a2.b reference to b
+        // * disconnect a1.b reference
+        assertEquals(partialUpdatedEntities.size(), 3);
+        storedEntities = entityStore.getByIds(ImmutableList.of(a1.getGuid(), a2.getGuid(), b.getGuid()));
+        storedEntity = storedEntities.getEntity(a2.getGuid());
+        verifyReferenceValue(storedEntity, "b", b.getGuid());
+        storedEntity = storedEntities.getEntity(b.getGuid());
+        verifyReferenceValue(storedEntity, "a", a2.getGuid());
+        storedEntity = storedEntities.getEntity(a1.getGuid());
+        Object refValue = storedEntity.getAttribute("b");
+        verify_testInverseReferenceAutoUpdate_NonComposite_OneToOne(storedEntities.getEntity(a1.getGuid()), storedEntities.getEntity(b.getGuid()));
+    }
+
+    protected abstract void verify_testInverseReferenceAutoUpdate_NonComposite_OneToOne(AtlasEntity a1, AtlasEntity b);
+
+    @Test
+    public void testInverseReferenceAutoUpdate_NonComposite_ManyToMany() throws Exception {
+        AtlasEntityType bType = typeRegistry.getEntityTypeByName("B");
+        AtlasEntity a1 = new AtlasEntity("A");
+        a1.setAttribute(NAME, TestUtilsV2.randomString());
+        AtlasEntity a2 = new AtlasEntity("A");
+        a2.setAttribute(NAME, TestUtilsV2.randomString());
+        AtlasEntity a3 = new AtlasEntity("A");
+        a3.setAttribute(NAME, TestUtilsV2.randomString());
+        AtlasEntity b1 = new AtlasEntity("B");
+        b1.setAttribute(NAME, TestUtilsV2.randomString());
+        AtlasEntity b2 = new AtlasEntity("B");
+        b2.setAttribute(NAME, TestUtilsV2.randomString());
+        AtlasEntitiesWithExtInfo atlasEntitiesWithExtInfo = new AtlasEntitiesWithExtInfo();
+        atlasEntitiesWithExtInfo.addEntity(a1);
+        atlasEntitiesWithExtInfo.addEntity(a2);
+        atlasEntitiesWithExtInfo.addEntity(a3);
+        atlasEntitiesWithExtInfo.addEntity(b1);
+        atlasEntitiesWithExtInfo.addEntity(b2);
+        AtlasEntityStream entityStream = new AtlasEntityStream(atlasEntitiesWithExtInfo);
+        EntityMutationResponse response = entityStore.createOrUpdate(entityStream , false);
+
+        AtlasEntity b1ForPartialUpdate = new AtlasEntity("B");
+        b1ForPartialUpdate.setAttribute("manyToManyA", ImmutableList.of(AtlasTypeUtil.getAtlasObjectId(a1), AtlasTypeUtil.getAtlasObjectId(a2)));
+        init();
+        response = entityStore.updateByUniqueAttributes(bType, Collections.<String, Object>singletonMap(NAME, b1.getAttribute(NAME)), new AtlasEntityWithExtInfo(b1ForPartialUpdate));
+        List<AtlasEntityHeader> partialUpdatedEntities = response.getPartialUpdatedEntities();
+        assertEquals(partialUpdatedEntities.size(), 3);
+        AtlasEntitiesWithExtInfo storedEntities = entityStore.getByIds(ImmutableList.of(a1.getGuid(), a2.getGuid(), b1.getGuid()));
+        AtlasEntity storedEntity = storedEntities.getEntity(b1.getGuid());
+        verifyReferenceList(storedEntity, "manyToManyA", ImmutableList.of(AtlasTypeUtil.getAtlasObjectId(a1), AtlasTypeUtil.getAtlasObjectId(a2)));
+        storedEntity = storedEntities.getEntity(a1.getGuid());
+        verifyReferenceList(storedEntity, "manyB", ImmutableList.of(AtlasTypeUtil.getAtlasObjectId(b1)));
+        storedEntity = storedEntities.getEntity(a2.getGuid());
+        verifyReferenceList(storedEntity, "manyB", ImmutableList.of(AtlasTypeUtil.getAtlasObjectId(b1)));
+    }
+
+    @Test
+    public void testInverseReferenceAutoUpdate_Map() throws Exception {
+        AtlasEntity a1 = new AtlasEntity("A");
+        a1.setAttribute(NAME, TestUtilsV2.randomString());
+        AtlasEntity b1 = new AtlasEntity("B");
+        b1.setAttribute(NAME, TestUtilsV2.randomString());
+        AtlasEntity b2 = new AtlasEntity("B");
+        b2.setAttribute(NAME, TestUtilsV2.randomString());
+        AtlasEntity b3 = new AtlasEntity("B");
+        b3.setAttribute(NAME, TestUtilsV2.randomString());
+        AtlasEntitiesWithExtInfo atlasEntitiesWithExtInfo = new AtlasEntitiesWithExtInfo();
+        atlasEntitiesWithExtInfo.addEntity(a1);
+        atlasEntitiesWithExtInfo.addEntity(b1);
+        atlasEntitiesWithExtInfo.addEntity(b2);
+        atlasEntitiesWithExtInfo.addEntity(b3);
+        AtlasEntityStream entityStream = new AtlasEntityStream(atlasEntitiesWithExtInfo);
+        EntityMutationResponse response = entityStore.createOrUpdate(entityStream , false);
+
+        AtlasEntityType aType = typeRegistry.getEntityTypeByName("A");
+        AtlasEntity aForPartialUpdate = new AtlasEntity("A");
+        aForPartialUpdate.setAttribute("mapToB", ImmutableMap.<String, AtlasObjectId>of("b1", AtlasTypeUtil.getAtlasObjectId(b1), "b2", AtlasTypeUtil.getAtlasObjectId(b2)));
+        init();
+        response = entityStore.updateByUniqueAttributes(aType, Collections.<String, Object>singletonMap(NAME, a1.getAttribute(NAME)), new AtlasEntityWithExtInfo(aForPartialUpdate));
+        List<AtlasEntityHeader> partialUpdatedEntities = response.getPartialUpdatedEntities();
+        // Verify 3 entities were updated:
+        // * set a1.mapToB to "b1"->b1, "b2"->b2
+        // * set b1.mappedFromA to a1
+        // * set b2.mappedFromA to a1
+        assertEquals(partialUpdatedEntities.size(), 3);
+        AtlasEntitiesWithExtInfo storedEntities = entityStore.getByIds(ImmutableList.of(a1.getGuid(), b2.getGuid(), b1.getGuid()));
+        AtlasEntity storedEntity = storedEntities.getEntity(a1.getGuid());
+        Object value = storedEntity.getAttribute("mapToB");
+        assertTrue(value instanceof Map);
+        Map<String, AtlasObjectId> refMap = (Map<String, AtlasObjectId>) value;
+        assertEquals(refMap.size(), 2);
+        AtlasObjectId referencedEntityId = refMap.get("b1");
+        assertEquals(referencedEntityId, AtlasTypeUtil.getAtlasObjectId(b1));
+        referencedEntityId = refMap.get("b2");
+        assertEquals(referencedEntityId, AtlasTypeUtil.getAtlasObjectId(b2));
+        storedEntity = storedEntities.getEntity(b1.getGuid());
+        verifyReferenceValue(storedEntity, "mappedFromA", a1.getGuid());
+        storedEntity = storedEntities.getEntity(b2.getGuid());
+        verifyReferenceValue(storedEntity, "mappedFromA", a1.getGuid());
+
+        aForPartialUpdate.setAttribute("mapToB", ImmutableMap.<String, AtlasObjectId>of("b3", AtlasTypeUtil.getAtlasObjectId(b3)));
+        init();
+        response = entityStore.updateByUniqueAttributes(aType, Collections.<String, Object>singletonMap(NAME, a1.getAttribute(NAME)), new AtlasEntityWithExtInfo(aForPartialUpdate));
+        partialUpdatedEntities = response.getPartialUpdatedEntities();
+        // Verify 4 entities were updated:
+        // * set a1.mapToB to "b3"->b3
+        // * set b3.mappedFromA to a1
+        // * disconnect b1.mappedFromA
+        // * disconnect b2.mappedFromA
+        assertEquals(partialUpdatedEntities.size(), 4);
+        storedEntities = entityStore.getByIds(ImmutableList.of(a1.getGuid(), b2.getGuid(), b1.getGuid(), b3.getGuid()));
+        AtlasEntity storedB3 = storedEntities.getEntity(b3.getGuid());
+        verifyReferenceValue(storedB3, "mappedFromA", a1.getGuid());
+        verify_testInverseReferenceAutoUpdate_Map(storedEntities.getEntity(a1.getGuid()), storedEntities.getEntity(b1.getGuid()), storedEntities.getEntity(b2.getGuid()), storedB3);
+    }
+
+    protected abstract void verify_testInverseReferenceAutoUpdate_Map(AtlasEntity a1, AtlasEntity b1, AtlasEntity b2, AtlasEntity b3);
+
+    protected void verifyReferenceValue(AtlasEntity entity, String refName, String expectedGuid) {
+        Object refValue = entity.getAttribute(refName);
+        if (expectedGuid == null) {
+            assertNull(refValue);
+        }
+        else {
+            assertTrue(refValue instanceof AtlasObjectId);
+            AtlasObjectId referencedObjectId = (AtlasObjectId) refValue;
+            assertEquals(referencedObjectId.getGuid(), expectedGuid);
+        }
+    }
+
+    protected void verifyReferenceList(AtlasEntity entity, String refName, List<AtlasObjectId> expectedValues) {
+        Object refValue = entity.getAttribute(refName);
+        assertTrue(refValue instanceof List);
+        List<AtlasObjectId> refList = (List<AtlasObjectId>) refValue;
+        assertEquals(refList.size(), expectedValues.size());
+        if (expectedValues.size() > 0) {
+            assertTrue(refList.containsAll(expectedValues));
+        }
+    }
+}
diff --git a/repository/src/test/java/org/apache/atlas/repository/userprofile/UserProfileServiceTest.java b/repository/src/test/java/org/apache/atlas/repository/userprofile/UserProfileServiceTest.java
new file mode 100644
index 0000000..0532f16
--- /dev/null
+++ b/repository/src/test/java/org/apache/atlas/repository/userprofile/UserProfileServiceTest.java
@@ -0,0 +1,280 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.repository.userprofile;
+
+import org.apache.atlas.AtlasErrorCode;
+import org.apache.atlas.TestModules;
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.SearchFilter;
+import org.apache.atlas.model.discovery.SearchParameters;
+import org.apache.atlas.model.profile.AtlasUserProfile;
+import org.apache.atlas.model.profile.AtlasUserSavedSearch;
+import org.apache.atlas.model.typedef.AtlasTypesDef;
+import org.apache.atlas.repository.util.FilterUtil;
+import org.apache.atlas.store.AtlasTypeDefStore;
+import org.apache.atlas.type.AtlasType;
+import org.apache.atlas.type.AtlasTypeRegistry;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+
+import javax.inject.Inject;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.apache.atlas.model.profile.AtlasUserSavedSearch.SavedSearchType.BASIC;
+import static org.apache.atlas.repository.impexp.ZipFileResourceTestUtils.loadModelFromJson;
+import static org.testng.Assert.*;
+
+@Guice(modules = TestModules.TestOnlyModule.class)
+public class UserProfileServiceTest {
+    private UserProfileService userProfileService;
+    private AtlasTypeDefStore  typeDefStore;
+    private int                max_searches = 4;
+
+    @Inject
+    public void UserProfileServiceTest(AtlasTypeRegistry  typeRegistry,
+                                       AtlasTypeDefStore  typeDefStore,
+                                       UserProfileService userProfileService) throws IOException, AtlasBaseException {
+        this.typeDefStore       = typeDefStore;
+        this.userProfileService = userProfileService;
+
+        loadModelFromJson("0010-base_model.json", typeDefStore, typeRegistry);
+    }
+
+    @Test
+    public void filterInternalType() throws AtlasBaseException {
+        SearchFilter searchFilter = new SearchFilter();
+        AtlasTypesDef filteredTypeDefs = typeDefStore.searchTypesDef(searchFilter);
+        int maxTypeDefs = filteredTypeDefs.getEntityDefs().size();
+
+        FilterUtil.addParamsToHideInternalType(searchFilter);
+        filteredTypeDefs = typeDefStore.searchTypesDef(searchFilter);
+
+        assertNotNull(filteredTypeDefs);
+        assertEquals(filteredTypeDefs.getEntityDefs().size(), maxTypeDefs - 3);
+    }
+
+    @Test
+    public void createsNewProfile() throws AtlasBaseException {
+        int i = 0;
+        assertSaveLoadUserProfile(i++);
+        assertSaveLoadUserProfile(i);
+    }
+
+    @Test(dependsOnMethods = { "createsNewProfile", "savesQueryForAnNonExistentUser" }, expectedExceptions = AtlasBaseException.class)
+    public void atteptsToAddAlreadyExistingQueryForAnExistingUser() throws AtlasBaseException {
+        SearchParameters expectedSearchParameter = getActualSearchParameters();
+
+        for (int i = 0; i < 2; i++) {
+            String userName = getIndexBasedUserName(i);
+
+            for (int j = 0; j < max_searches; j++) {
+                String queryName = getIndexBasedQueryName(j);
+                AtlasUserSavedSearch expected = getDefaultSavedSearch(userName, queryName, expectedSearchParameter);
+                AtlasUserSavedSearch actual = userProfileService.addSavedSearch(expected);
+
+                assertNotNull(actual);
+                assertNotNull(actual.getGuid());
+                assertEquals(actual.getOwnerName(), expected.getOwnerName());
+                assertEquals(actual.getName(), expected.getName());
+                assertEquals(actual.getSearchType(), expected.getSearchType());
+                assertEquals(actual.getSearchParameters(), expected.getSearchParameters());
+            }
+        }
+    }
+
+    @Test(dependsOnMethods = { "createsNewProfile", "savesQueryForAnNonExistentUser", "atteptsToAddAlreadyExistingQueryForAnExistingUser" })
+    public void savesExistingQueryForAnExistingUser() throws AtlasBaseException {
+        SearchParameters expectedSearchParameter = getActualSearchParameters();
+
+        for (int i = 0; i < 2; i++) {
+            String userName = getIndexBasedUserName(i);
+
+            for (int j = 4; j < max_searches + 6; j++) {
+                String queryName = getIndexBasedQueryName(j);
+                AtlasUserSavedSearch actual = userProfileService.addSavedSearch(getDefaultSavedSearch(userName, queryName, expectedSearchParameter));
+                assertNotNull(actual);
+
+                AtlasUserSavedSearch savedSearch = userProfileService.getSavedSearch(userName, queryName);
+                assertNotNull(savedSearch);
+                assertEquals(savedSearch.getSearchParameters(), expectedSearchParameter);
+            }
+        }
+    }
+
+    private SearchParameters getActualSearchParameters() {
+        SearchParameters sp = new SearchParameters();
+        sp.setClassification("test-classification");
+        sp.setQuery("g.v().has('__guid').__guid.toList()");
+        sp.setLimit(10);
+        sp.setTypeName("some-type");
+
+        return sp;
+    }
+
+    @Test(dependsOnMethods = "createsNewProfile")
+    public void savesQueryForAnNonExistentUser() throws AtlasBaseException {
+        String expectedUserName = getIndexBasedUserName(0);
+        String expectedQueryName = "testQuery";
+        SearchParameters expectedSearchParam = getActualSearchParameters();
+        AtlasUserSavedSearch expectedSavedSearch = getDefaultSavedSearch(expectedUserName, expectedQueryName, expectedSearchParam);
+
+        AtlasUserSavedSearch actual = userProfileService.addSavedSearch(expectedSavedSearch);
+        assertEquals(actual.getOwnerName(), expectedUserName);
+        assertEquals(actual.getName(), expectedQueryName);
+    }
+
+    private AtlasUserSavedSearch getDefaultSavedSearch(String userName, String queryName, SearchParameters expectedSearchParam) {
+        return new AtlasUserSavedSearch(userName, queryName,
+                BASIC, expectedSearchParam);
+    }
+
+    @Test(dependsOnMethods = "createsNewProfile")
+    public void savesMultipleQueriesForUser() throws AtlasBaseException {
+        final String userName = getIndexBasedUserName(0);
+        createUserWithSavedQueries(userName);
+    }
+
+    private void createUserWithSavedQueries(String userName) throws AtlasBaseException {
+        SearchParameters actualSearchParameter = getActualSearchParameters();
+
+        saveQueries(userName, actualSearchParameter);
+        for (int i = 0; i < max_searches; i++) {
+            AtlasUserSavedSearch savedSearch = userProfileService.getSavedSearch(userName, getIndexBasedQueryName(i));
+            assertEquals(savedSearch.getName(), getIndexBasedQueryName(i));
+            assertEquals(savedSearch.getSearchParameters(), actualSearchParameter);
+        }
+    }
+
+    private void saveQueries(String userName, SearchParameters sp) throws AtlasBaseException {
+        for (int i = 0; i < max_searches; i++) {
+            userProfileService.addSavedSearch(getDefaultSavedSearch(userName, getIndexBasedQueryName(i), sp));
+        }
+    }
+
+    @Test(dependsOnMethods = {"createsNewProfile", "savesMultipleQueriesForUser"})
+    public void verifyQueryNameListForUser() throws AtlasBaseException {
+        final String userName = getIndexBasedUserName(0);
+
+        List<AtlasUserSavedSearch> list = userProfileService.getSavedSearches(userName);
+        List<String> names = getIndexBasedQueryNamesList();
+        for (int i = 0; i < names.size(); i++) {
+            assertTrue(names.contains(list.get(i).getName()), list.get(i).getName() + " failed!");
+        }
+    }
+
+    @Test(dependsOnMethods = {"createsNewProfile", "savesMultipleQueriesForUser"}, enabled = false)
+    public void verifyQueryConversionFromJSON() throws AtlasBaseException {
+        List<AtlasUserSavedSearch> list = userProfileService.getSavedSearches("first-0");
+
+        for (int i = 0; i < max_searches; i++) {
+            SearchParameters sp = list.get(i).getSearchParameters();
+            String json = AtlasType.toJson(sp);
+            assertEquals(AtlasType.toJson(getActualSearchParameters()).replace("\n", "").replace(" ", ""), json);
+        }
+    }
+
+    @Test(dependsOnMethods = {"createsNewProfile", "savesMultipleQueriesForUser"})
+    public void updateSearch() throws AtlasBaseException {
+        final String queryName = getIndexBasedQueryName(0);
+        String userName = getIndexBasedUserName(0);
+        AtlasUserSavedSearch expected = userProfileService.getSavedSearch(userName, queryName);
+        assertNotNull(expected);
+
+        SearchParameters sp = expected.getSearchParameters();
+        sp.setClassification("new-classification");
+
+        AtlasUserSavedSearch actual = userProfileService.updateSavedSearch(expected);
+
+        assertNotNull(actual);
+        assertNotNull(actual.getSearchParameters());
+        assertEquals(actual.getSearchParameters().getClassification(), expected.getSearchParameters().getClassification());
+    }
+
+    @Test(dependsOnMethods = {"createsNewProfile", "savesMultipleQueriesForUser", "verifyQueryNameListForUser"}, expectedExceptions = AtlasBaseException.class)
+    public void deleteUsingGuid() throws AtlasBaseException {
+        final String queryName = getIndexBasedQueryName(1);
+        String userName = getIndexBasedUserName(0);
+
+        AtlasUserSavedSearch expected = userProfileService.getSavedSearch(userName, queryName);
+        assertNotNull(expected);
+
+        userProfileService.deleteSavedSearch(expected.getGuid());
+        userProfileService.getSavedSearch(userName, queryName);
+    }
+
+    @Test(dependsOnMethods = {"createsNewProfile", "savesMultipleQueriesForUser", "verifyQueryNameListForUser"})
+    public void deleteSavedQuery() throws AtlasBaseException {
+        final String userName = getIndexBasedUserName(0);
+        AtlasUserProfile expected = userProfileService.getUserProfile(userName);
+        assertNotNull(expected);
+
+        int new_max_searches = expected.getSavedSearches().size();
+        String queryNameToBeDeleted = getIndexBasedQueryName(max_searches - 2);
+        userProfileService.deleteSearchBySearchName(userName, queryNameToBeDeleted);
+
+        List<AtlasUserSavedSearch> savedSearchList = userProfileService.getSavedSearches(userName);
+        assertEquals(savedSearchList.size(), new_max_searches - 1);
+    }
+
+    @Test(dependsOnMethods = {"createsNewProfile", "savesMultipleQueriesForUser", "verifyQueryNameListForUser"})
+    void deleteUser() throws AtlasBaseException {
+        String userName = getIndexBasedUserName(1);
+
+        userProfileService.deleteUserProfile(userName);
+        try {
+            userProfileService.getUserProfile(userName);
+        }
+        catch(AtlasBaseException ex) {
+            assertEquals(ex.getAtlasErrorCode().name(), AtlasErrorCode.INSTANCE_BY_UNIQUE_ATTRIBUTE_NOT_FOUND.name());
+        }
+    }
+
+    private void assertSaveLoadUserProfile(int i) throws AtlasBaseException {
+        String s = String.valueOf(i);
+        AtlasUserProfile expected = getAtlasUserProfile(i);
+
+        AtlasUserProfile actual = userProfileService.saveUserProfile(expected);
+        assertNotNull(actual);
+        assertEquals(expected.getName(), actual.getName());
+        assertEquals(expected.getFullName(), actual.getFullName());
+        assertNotNull(actual.getGuid());
+    }
+
+    public static AtlasUserProfile getAtlasUserProfile(Integer s) {
+        return new AtlasUserProfile(getIndexBasedUserName(s), String.format("first-%s last-%s", s, s));
+    }
+
+    private static String getIndexBasedUserName(Integer i) {
+        return String.format("first-%s", i.toString());
+    }
+
+    private static String getIndexBasedQueryName(Integer i) {
+        return String.format("testQuery-%s", i.toString());
+    }
+
+    public List<String> getIndexBasedQueryNamesList() {
+        List<String> list = new ArrayList<>();
+        for (int i = 0; i < max_searches; i++) {
+            list.add(getIndexBasedQueryName(i));
+        }
+
+        return list;
+    }
+}
diff --git a/repository/src/test/java/org/apache/atlas/services/MetricsServiceTest.java b/repository/src/test/java/org/apache/atlas/services/MetricsServiceTest.java
new file mode 100644
index 0000000..5165bcb
--- /dev/null
+++ b/repository/src/test/java/org/apache/atlas/services/MetricsServiceTest.java
@@ -0,0 +1,123 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.services;
+
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.metrics.AtlasMetrics;
+import org.apache.atlas.repository.graphdb.AtlasGraph;
+import org.apache.atlas.type.AtlasTypeRegistry;
+import org.apache.commons.configuration.Configuration;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.*;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
+public class MetricsServiceTest {
+    private Configuration mockConfig = mock(Configuration.class);
+    private AtlasTypeRegistry mockTypeRegistry = mock(AtlasTypeRegistry.class);
+    private AtlasGraph mockGraph = mock(AtlasGraph.class);
+    private MetricsService metricsService;
+
+    private List<Map> mockMapList = new ArrayList<>();
+    private Number mockCount = 10;
+
+    @BeforeClass
+    public void init() throws AtlasBaseException {
+        Map<String, Object> mockMap = new HashMap<>();
+        mockMap.put("a", 1);
+        mockMap.put("b", 2);
+        mockMap.put("c", 3);
+        mockMapList.add(mockMap);
+
+        when(mockConfig.getInt(anyString(), anyInt())).thenReturn(5);
+        assertEquals(mockConfig.getInt("test", 1), 5);
+        when(mockConfig.getString(anyString(), anyString()))
+                .thenReturn("count()", "count()", "count()", "count()", "count()", "toList()", "count()", "toList()");
+        when(mockTypeRegistry.getAllEntityDefNames()).thenReturn(Arrays.asList("a", "b", "c"));
+        setupMockGraph();
+
+        metricsService = new MetricsService(mockConfig, mockGraph);
+    }
+
+    private void setupMockGraph() throws AtlasBaseException {
+        if (mockGraph == null) mockGraph = mock(AtlasGraph.class);
+        when(mockGraph.executeGremlinScript(anyString(), eq(false))).thenAnswer(new Answer<Object>() {
+            @Override
+            public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
+                if (((String)invocationOnMock.getArguments()[0]).contains("count()")) {
+                    return mockCount;
+                } else {
+                    return mockMapList;
+                }
+            }
+        });
+    }
+
+    @Test
+    public void testGetMetrics() throws InterruptedException, AtlasBaseException {
+        assertNotNull(metricsService);
+        AtlasMetrics metrics = metricsService.getMetrics(false);
+        assertNotNull(metrics);
+        Number aCount = metrics.getMetric("entity", "a");
+        assertNotNull(aCount);
+        assertEquals(aCount, 1);
+
+        Number bCount = metrics.getMetric("entity", "b");
+        assertNotNull(bCount);
+        assertEquals(bCount, 2);
+
+        Number cCount = metrics.getMetric("entity", "c");
+        assertNotNull(cCount);
+        assertEquals(cCount, 3);
+
+        Number aTags = metrics.getMetric("tag", "a");
+        assertNotNull(aTags);
+        assertEquals(aTags, 1);
+
+        Number bTags = metrics.getMetric("tag", "b");
+        assertNotNull(bTags);
+        assertEquals(bTags, 2);
+
+        Number cTags = metrics.getMetric("tag", "c");
+        assertNotNull(cTags);
+        assertEquals(cTags, 3);
+
+        verify(mockGraph, atLeastOnce()).executeGremlinScript(anyString(), anyBoolean());
+
+        // Subsequent call within the cache timeout window
+        metricsService.getMetrics(false);
+        verifyZeroInteractions(mockGraph);
+
+        // Now test the cache refresh
+        Thread.sleep(6000);
+        metricsService.getMetrics(true);
+        verify(mockGraph, atLeastOnce()).executeGremlinScript(anyString(), anyBoolean());
+    }
+}
diff --git a/repository/src/test/java/org/apache/atlas/utils/ObjectUpdateSynchronizerTest.java b/repository/src/test/java/org/apache/atlas/utils/ObjectUpdateSynchronizerTest.java
new file mode 100644
index 0000000..03ebae4
--- /dev/null
+++ b/repository/src/test/java/org/apache/atlas/utils/ObjectUpdateSynchronizerTest.java
@@ -0,0 +1,218 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.utils;
+
+import org.apache.atlas.GraphTransactionInterceptor;
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.commons.lang.RandomStringUtils;
+import org.springframework.util.CollectionUtils;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+
+public class ObjectUpdateSynchronizerTest {
+    private static final GraphTransactionInterceptor.ObjectUpdateSynchronizer objectUpdateSynchronizer = new GraphTransactionInterceptor.ObjectUpdateSynchronizer();
+
+    private final List<Integer> outputList = new ArrayList<>();
+    private final int MAX_COUNT = 10;
+
+    class CounterThread extends Thread {
+        String ids[];
+        public CounterThread(String id) {
+            this.ids = new String[1];
+            this.ids[0] = id;
+        }
+
+        public void setIds(String... ids) {
+            this.ids = ids;
+        }
+
+        public void run() {
+            objectUpdateSynchronizer.lockObject(CollectionUtils.arrayToList(ids));
+            for (int i = 0; i < MAX_COUNT; i++) {
+                outputList.add(i);
+                RandomStringUtils.randomAlphabetic(20);
+            }
+
+            objectUpdateSynchronizer.releaseLockedObjects();
+        }
+    }
+
+    @BeforeMethod
+    public void clearOutputList() {
+        outputList.clear();
+    }
+
+    @Test
+    public void singleThreadRun() throws InterruptedException {
+        verifyMultipleThreadRun(1);
+    }
+
+    @Test
+    public void twoThreadsAccessingDifferntGuids_DoNotSerialize() throws InterruptedException {
+        CounterThread th[] = getCounterThreads(false, 2);
+
+        startCounterThreads(th);
+        waitForThreadsToEnd(th);
+        assertArrayNotEquals(populateExpectedArrayOutput(2));
+    }
+
+    @Test
+    public void twoThreadsAccessingSameGuid_Serialize() throws InterruptedException {
+        verifyMultipleThreadRun(2);
+    }
+
+    @Test
+    public void severalThreadsAccessingSameGuid_Serialize() throws InterruptedException {
+        verifyMultipleThreadRun(10);
+    }
+
+    @Test
+    public void severalThreadsSequentialAccessingListOfGuids() throws InterruptedException {
+        CounterThread th[] = getCounterThreads(false, 10);
+        int i = 0;
+        th[i++].setIds("1", "2", "3", "4", "5");
+        th[i++].setIds("1", "2", "3", "4");
+        th[i++].setIds("1", "2", "3");
+        th[i++].setIds("1", "2");
+        th[i++].setIds("1");
+        th[i++].setIds("1", "2");
+        th[i++].setIds("1", "2", "3");
+        th[i++].setIds("1", "2", "3", "4");
+        th[i++].setIds("1", "2", "3", "4", "5");
+        th[i++].setIds("1");
+
+        startCounterThreads(th);
+        waitForThreadsToEnd(th);
+        assertArrayEquals(populateExpectedArrayOutput(th.length));
+    }
+
+    @Test
+    public void severalThreadsNonSequentialAccessingListOfGuids() throws InterruptedException {
+        CounterThread th[] = getCounterThreads(false, 5);
+        int i = 0;
+        th[i++].setIds("2", "1", "3", "4", "5");
+        th[i++].setIds("3", "2", "4", "1");
+        th[i++].setIds("2", "3", "1");
+        th[i++].setIds("1", "2");
+        th[i++].setIds("1");
+
+        startCounterThreads(th);
+        waitForThreadsToEnd(th);
+        assertArrayEquals(populateExpectedArrayOutput(th.length));
+    }
+
+    @Test
+    public void severalThreadsAccessingOverlappingListOfGuids() throws InterruptedException {
+        CounterThread th[] = getCounterThreads(false, 5);
+        int i = 0;
+        th[i++].setIds("1", "2", "3", "4", "5");
+        th[i++].setIds("3", "4", "5", "6");
+        th[i++].setIds("5", "6", "7");
+        th[i++].setIds("7", "8");
+        th[i++].setIds("8");
+
+        startCounterThreads(th);
+        waitForThreadsToEnd(th);
+        assertArrayNotEquals(populateExpectedArrayOutput(th.length));
+    }
+
+
+    @Test
+    public void severalThreadsAccessingOverlappingListOfGuids2() throws InterruptedException {
+        CounterThread th[] = getCounterThreads(false, 3);
+        int i = 0;
+        th[i++].setIds("1", "2", "3", "4", "5");
+        th[i++].setIds("6", "7", "8", "9");
+        th[i++].setIds("4", "5", "6");
+
+        startCounterThreads(th);
+        waitForThreadsToEnd(th);
+        assertArrayNotEquals(populateExpectedArrayOutput(th.length));
+    }
+
+    @Test
+    public void severalThreadsAccessingOverlappingListOfGuidsEnsuringSerialOutput() throws InterruptedException {
+        CounterThread th[] = getCounterThreads(false, 5);
+        int i = 0;
+        th[i++].setIds("1", "2", "3", "4", "7");
+        th[i++].setIds("3", "4", "5", "7");
+        th[i++].setIds("5", "6", "7");
+        th[i++].setIds("7", "8");
+        th[i++].setIds("7");
+
+        startCounterThreads(th);
+        waitForThreadsToEnd(th);
+        assertArrayEquals(populateExpectedArrayOutput(th.length));
+    }
+
+    private void verifyMultipleThreadRun(int limit) throws InterruptedException {
+        CounterThread[] th = getCounterThreads(limit);
+        startCounterThreads(th);
+        waitForThreadsToEnd(th);
+        assertArrayEquals(populateExpectedArrayOutput(limit));
+    }
+
+    private void startCounterThreads(CounterThread[] th) {
+        for (int i = 0; i < th.length; i++) {
+            th[i].start();
+        }
+    }
+    private CounterThread[] getCounterThreads(int limit) {
+        return getCounterThreads(true, limit);
+    }
+
+    private CounterThread[] getCounterThreads(boolean sameId, int limit) {
+        CounterThread th[] = new CounterThread[limit];
+        for (Integer i = 0; i < limit; i++) {
+            th[i] = new CounterThread(sameId ? "1" : i.toString());
+        }
+        return th;
+    }
+
+
+    private void assertArrayEquals(List<Integer> expected) {
+        assertEquals(outputList.toArray(), expected.toArray());
+    }
+
+    private void assertArrayNotEquals(List<Integer> expected) {
+        assertFalse(ArrayUtils.isEquals(outputList.toArray(), expected));
+    }
+
+    private void waitForThreadsToEnd(CounterThread... threads) throws InterruptedException {
+        for (Thread t : threads) {
+            t.join();
+        }
+    }
+
+    private List<Integer> populateExpectedArrayOutput(int limit) {
+        List<Integer> list = new ArrayList<>();
+        for (int i = 0; i < limit*MAX_COUNT; i+=MAX_COUNT) {
+            for (int j = 0; j < MAX_COUNT; j++) {
+                list.add(j);
+            }
+        }
+
+        return list;
+    }
+}
diff --git a/webapp/src/test/java/org/apache/atlas/util/RestUtilsTest.java b/webapp/src/test/java/org/apache/atlas/util/RestUtilsTest.java
new file mode 100644
index 0000000..0d4af1e
--- /dev/null
+++ b/webapp/src/test/java/org/apache/atlas/util/RestUtilsTest.java
@@ -0,0 +1,195 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.util;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.*;
+
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.typedef.AtlasBaseTypeDef;
+import org.apache.atlas.model.typedef.AtlasEntityDef;
+import org.apache.atlas.model.typedef.AtlasStructDef;
+import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
+import org.apache.atlas.model.typedef.AtlasTypesDef;
+import org.apache.atlas.repository.Constants;
+import org.apache.atlas.repository.converters.TypeConverterUtil;
+import org.apache.atlas.repository.graphdb.AtlasVertex;
+import org.apache.atlas.repository.store.graph.v1.AtlasGraphUtilsV1;
+import org.apache.atlas.repository.store.graph.v1.AtlasStructDefStoreV1;
+import org.apache.atlas.repository.store.graph.v1.AtlasTypeDefGraphStoreV1;
+import org.apache.atlas.type.AtlasEntityType;
+import org.apache.atlas.type.AtlasStructType;
+import org.apache.atlas.type.AtlasStructType.AtlasAttribute;
+import org.apache.atlas.type.AtlasType;
+import org.apache.atlas.type.AtlasTypeRegistry;
+import org.apache.atlas.type.AtlasTypeRegistry.AtlasTransientTypeRegistry;
+import org.apache.atlas.typesystem.types.DataTypes.TypeCategory;
+import org.apache.atlas.v1.model.typedef.*;
+import org.apache.atlas.v1.typesystem.types.utils.TypesUtil;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * Validates that conversion from V1 to legacy types (and back) is consistent.  This also tests
+ * that the conversion logic in AtlasStructDefStoreV1 is consistent with the conversion logic
+ * in RestUtils.  This tests particularly focuses on composite attributes, since a defect was
+ * found in that area.
+ */
+public class RestUtilsTest {
+
+    @Test(enabled=false)
+    // FIXME: On conversion back to V1, reverse attribute name
+    // "containingDatabase"
+    // in tables attribute in "database" type is lost.  See ATLAS-1528.
+    public void testBidirectonalCompositeMappingConsistent() throws AtlasBaseException {
+
+        ClassTypeDefinition dbV1Type = TypesUtil.createClassTypeDef("database", "", Collections.emptySet(),
+                                           new AttributeDefinition("tables", AtlasBaseTypeDef.getArrayTypeName("table"),
+                                                                   Multiplicity.OPTIONAL, true, "containingDatabase"));
+
+        ClassTypeDefinition tableV1Type = TypesUtil.createClassTypeDef("table", "", Collections.emptySet(),
+                                            new AttributeDefinition("containingDatabase", "database",
+                                                                    Multiplicity.OPTIONAL, false, "tables"));
+
+        testV1toV2toV1Conversion(Arrays.asList(dbV1Type, tableV1Type), new boolean[] { true, false });
+    }
+
+    @Test(enabled=false)
+    // FIXME: On conversion back to V1, reverse attribute name
+    // "containingDatabase" is lost
+    // in "table" attribute in "database".  See ATLAS-1528.
+    public void testBidirectonalNonCompositeMappingConsistent() throws AtlasBaseException {
+        ClassTypeDefinition dbV1Type = TypesUtil.createClassTypeDef("database", "", Collections.emptySet(),
+                                        new AttributeDefinition("tables", AtlasBaseTypeDef.getArrayTypeName("table"),
+                                                                Multiplicity.OPTIONAL, false, "containingDatabase"));
+
+        ClassTypeDefinition tableV1Type = TypesUtil.createClassTypeDef("table", "", Collections.emptySet(),
+                                           new AttributeDefinition("containingDatabase", "database",
+                                                                   Multiplicity.OPTIONAL, false, "tables"));
+
+        testV1toV2toV1Conversion(Arrays.asList(dbV1Type, tableV1Type), new boolean[] { false, false });
+    }
+
+    private AtlasTypeDefGraphStoreV1 makeTypeStore(AtlasTypeRegistry reg) {
+        AtlasTypeDefGraphStoreV1 result = mock(AtlasTypeDefGraphStoreV1.class);
+
+        for (AtlasEntityType type : reg.getAllEntityTypes()) {
+            String      typeName = type.getTypeName();
+            AtlasVertex typeVertex = mock(AtlasVertex.class);
+
+            when(result.isTypeVertex(eq(typeVertex), any(TypeCategory.class))).thenReturn(true);
+            when(typeVertex.getProperty(eq(Constants.TYPE_CATEGORY_PROPERTY_KEY), eq(TypeCategory.class))).thenReturn(TypeCategory.CLASS);
+
+            String attributeListPropertyKey = AtlasGraphUtilsV1.getTypeDefPropertyKey(typeName);
+
+            when(typeVertex.getProperty(eq(attributeListPropertyKey), eq(List.class))).thenReturn(new ArrayList<>(type.getAllAttributes().keySet()));
+
+            for (AtlasAttribute attribute : type.getAllAttributes().values()) {
+                String attributeDefPropertyKey = AtlasGraphUtilsV1.getTypeDefPropertyKey(typeName, attribute.getName());
+                String attributeJson           = AtlasStructDefStoreV1.toJsonFromAttribute(attribute);
+
+                when(typeVertex.getProperty(eq(attributeDefPropertyKey), eq(String.class))).thenReturn(attributeJson);
+            }
+
+            when(result.findTypeVertexByName(eq(typeName))).thenReturn(typeVertex);
+        }
+
+        return result;
+    }
+
+    private AtlasAttributeDef convertToJsonAndBack(AtlasTypeRegistry registry, AtlasStructDef structDef, AtlasAttributeDef attributeDef, boolean compositeExpected) throws AtlasBaseException {
+        AtlasTypeDefGraphStoreV1 typeDefStore = makeTypeStore(registry);
+        AtlasStructType          structType   = (AtlasStructType) registry.getType(structDef.getName());
+        AtlasAttribute           attribute    = structType.getAttribute(attributeDef.getName());
+        String                   attribJson   = AtlasStructDefStoreV1.toJsonFromAttribute(attribute);
+        Map                      attrInfo     = AtlasType.fromJson(attribJson, Map.class);
+
+        Assert.assertEquals(attrInfo.get("isComposite"), compositeExpected);
+
+        return AtlasStructDefStoreV1.toAttributeDefFromJson(structDef, attrInfo, typeDefStore);
+    }
+
+    private void testV1toV2toV1Conversion(List<ClassTypeDefinition> typesToTest, boolean[] compositeExpected) throws AtlasBaseException {
+        List<AtlasEntityDef> convertedEntityDefs = convertV1toV2(typesToTest);
+        AtlasTypeRegistry    registry            = createRegistry(convertedEntityDefs);
+
+        for(int i = 0 ; i < convertedEntityDefs.size(); i++) {
+            AtlasEntityDef def =  convertedEntityDefs.get(i);
+
+            for (AtlasAttributeDef attrDef : def.getAttributeDefs()) {
+                AtlasAttributeDef converted = convertToJsonAndBack(registry, def, attrDef, compositeExpected[i]);
+
+                Assert.assertEquals(converted, attrDef);
+            }
+        }
+
+        List<ClassTypeDefinition> convertedBackTypeDefs = convertV2toV1(convertedEntityDefs);
+
+        for (int i = 0; i < typesToTest.size(); i++) {
+            ClassTypeDefinition convertedBack = convertedBackTypeDefs.get(i);
+
+            Assert.assertEquals(convertedBack, typesToTest.get(i));
+
+            List<AttributeDefinition> attributeDefinitions = convertedBack.getAttributeDefinitions();
+
+            if (attributeDefinitions.size() > 0) {
+                Assert.assertEquals(attributeDefinitions.get(0).getIsComposite(), compositeExpected[i]);
+            }
+        }
+    }
+
+    private List<ClassTypeDefinition> convertV2toV1(List<AtlasEntityDef> toConvert) throws AtlasBaseException {
+        AtlasTypeRegistry         reg    = createRegistry(toConvert);
+        List<ClassTypeDefinition> result = new ArrayList<>(toConvert.size());
+
+        for (int i = 0; i < toConvert.size(); i++) {
+            AtlasEntityDef      entityDef = toConvert.get(i);
+            AtlasEntityType     entity    = reg.getEntityTypeByName(entityDef.getName());
+            ClassTypeDefinition converted = TypeConverterUtil.toTypesDef(entity, reg).getClassTypes().get(0);
+
+            result.add(converted);
+        }
+
+        return result;
+    }
+
+    private AtlasTypeRegistry createRegistry(List<AtlasEntityDef> toConvert) throws AtlasBaseException {
+        AtlasTypeRegistry          reg = new AtlasTypeRegistry();
+        AtlasTransientTypeRegistry tmp = reg.lockTypeRegistryForUpdate();
+
+        tmp.addTypes(toConvert);
+        reg.releaseTypeRegistryForUpdate(tmp, true);
+
+        return reg;
+    }
+
+    private List<AtlasEntityDef> convertV1toV2(List<ClassTypeDefinition> types) throws AtlasBaseException {
+        List<ClassTypeDefinition> classTypeList       = new ArrayList(types);
+        TypesDef                  toConvert           = new TypesDef(Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), classTypeList);
+        String                    json                = AtlasType.toV1Json(toConvert);
+        AtlasTypeRegistry         emptyRegistry       = new AtlasTypeRegistry();
+        AtlasTypesDef             converted           = TypeConverterUtil.toAtlasTypesDef(json, emptyRegistry);
+        List<AtlasEntityDef>      convertedEntityDefs = converted.getEntityDefs();
+
+        return convertedEntityDefs;
+    }
+}
