Add collaboration feature

Issue-ID: SDC-767
Change-Id: I14fb4c1f54086ed03a56a7ff7fab9ecd40381795
Signed-off-by: talig <talig@amdocs.com>
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-config-lib/src/test/java/org/openecomp/sdc/applicationconfig/dao/ApplicationConfigImplDaoTest.java b/openecomp-be/lib/openecomp-core-lib/openecomp-config-lib/src/test/java/org/openecomp/sdc/applicationconfig/dao/ApplicationConfigImplDaoTest.java
index 6b5c5f9..e3d8765 100644
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-config-lib/src/test/java/org/openecomp/sdc/applicationconfig/dao/ApplicationConfigImplDaoTest.java
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-config-lib/src/test/java/org/openecomp/sdc/applicationconfig/dao/ApplicationConfigImplDaoTest.java
@@ -20,23 +20,6 @@
 
 package org.openecomp.sdc.applicationconfig.dao;
 
-import org.openecomp.core.utilities.applicationconfig.ApplicationConfig;
-import org.openecomp.core.utilities.applicationconfig.ApplicationConfigFactory;
-import org.openecomp.core.utilities.applicationconfig.dao.ApplicationConfigDao;
-import org.openecomp.core.utilities.applicationconfig.dao.ApplicationConfigDaoFactory;
-import org.openecomp.core.utilities.applicationconfig.dao.type.ApplicationConfigEntity;
-import org.openecomp.core.utilities.applicationconfig.type.ConfigurationData;
-import org.openecomp.core.utilities.file.FileUtils;
-import org.openecomp.sdc.common.errors.CoreException;
-import org.openecomp.sdc.common.errors.ErrorCategory;
-import org.openecomp.sdc.common.errors.ErrorCode;
-import org.openecomp.sdc.logging.api.Logger;
-import org.openecomp.sdc.logging.api.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
-
-
 public class ApplicationConfigImplDaoTest {
 
   /*
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-facade-lib/openecomp-facade-api/src/main/java/org/openecomp/core/factory/impl/AbstractFactoryBase.java b/openecomp-be/lib/openecomp-core-lib/openecomp-facade-lib/openecomp-facade-api/src/main/java/org/openecomp/core/factory/impl/AbstractFactoryBase.java
index 9353de6..7b53f34 100644
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-facade-lib/openecomp-facade-api/src/main/java/org/openecomp/core/factory/impl/AbstractFactoryBase.java
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-facade-lib/openecomp-facade-api/src/main/java/org/openecomp/core/factory/impl/AbstractFactoryBase.java
@@ -21,9 +21,6 @@
 package org.openecomp.core.factory.impl;
 
 
-import static org.openecomp.core.utilities.CommonMethods.isEmpty;
-import static org.openecomp.core.utilities.CommonMethods.newInstance;
-
 import org.openecomp.sdc.common.errors.CoreException;
 import org.openecomp.sdc.common.errors.ErrorCategory;
 import org.openecomp.sdc.common.errors.ErrorCode;
@@ -32,6 +29,9 @@
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
+import static org.openecomp.core.utilities.CommonMethods.isEmpty;
+import static org.openecomp.core.utilities.CommonMethods.newInstance;
+
 public abstract class AbstractFactoryBase {
 
   /**
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-nosqldb-lib/openecomp-nosqldb-api/src/main/java/org/openecomp/core/util/UniqueValueUtil.java b/openecomp-be/lib/openecomp-core-lib/openecomp-nosqldb-lib/openecomp-nosqldb-api/src/main/java/org/openecomp/core/util/UniqueValueUtil.java
index dce34a1..15e9cee 100644
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-nosqldb-lib/openecomp-nosqldb-api/src/main/java/org/openecomp/core/util/UniqueValueUtil.java
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-nosqldb-lib/openecomp-nosqldb-api/src/main/java/org/openecomp/core/util/UniqueValueUtil.java
@@ -32,7 +32,7 @@
 import java.util.Optional;
 
 public class UniqueValueUtil {
-  public static final String UNIQUE_VALUE_VIOLATION = "UNIQUE_VALUE_VIOLATION";
+  private static final String UNIQUE_VALUE_VIOLATION = "UNIQUE_VALUE_VIOLATION";
   private static final String UNIQUE_VALUE_VIOLATION_MSG = "%s with the value '%s' already exists.";
 
   private static final UniqueValueDao uniqueValueDao =
@@ -46,9 +46,7 @@
    * @param uniqueCombination the unique combination
    */
   public static void createUniqueValue(String type, String... uniqueCombination) {
-
-
-    mdcDataDebugMessage.debugEntryMessage(null, null);
+    mdcDataDebugMessage.debugEntryMessage(null);
 
     Optional<String> value = formatValue(uniqueCombination);
     if (!value.isPresent()) {
@@ -57,7 +55,7 @@
     validateUniqueValue(type, value.get(), uniqueCombination);
     uniqueValueDao.create(new UniqueValueEntity(type, value.get()));
 
-    mdcDataDebugMessage.debugExitMessage(null, null);
+    mdcDataDebugMessage.debugExitMessage(null);
   }
 
   /**
@@ -69,7 +67,7 @@
   public static void deleteUniqueValue(String type, String... uniqueCombination) {
 
 
-    mdcDataDebugMessage.debugEntryMessage(null, null);
+    mdcDataDebugMessage.debugEntryMessage(null);
 
     Optional<String> value = formatValue(uniqueCombination);
     if (!value.isPresent()) {
@@ -77,7 +75,7 @@
     }
     uniqueValueDao.delete(new UniqueValueEntity(type, value.get()));
 
-    mdcDataDebugMessage.debugExitMessage(null, null);
+    mdcDataDebugMessage.debugExitMessage(null);
   }
 
   /**
@@ -92,17 +90,14 @@
                                        String... uniqueContext) {
 
 
-    mdcDataDebugMessage.debugEntryMessage(null, null);
+    mdcDataDebugMessage.debugEntryMessage(null);
 
-    boolean nonEqual = (newValue != null) && (oldValue != null)
-            && !newValue.toLowerCase().equals(oldValue.toLowerCase());
-
-    if (nonEqual || newValue == null || oldValue == null) {
+    if (newValue == null || oldValue == null || !newValue.equalsIgnoreCase(oldValue)) {
       createUniqueValue(type, CommonMethods.concat(uniqueContext, new String[]{newValue}));
       deleteUniqueValue(type, CommonMethods.concat(uniqueContext, new String[]{oldValue}));
     }
 
-    mdcDataDebugMessage.debugExitMessage(null, null);
+    mdcDataDebugMessage.debugExitMessage(null);
   }
 
   /**
@@ -112,7 +107,7 @@
    * @param uniqueCombination the unique combination
    */
   public static void validateUniqueValue(String type, String... uniqueCombination) {
-    mdcDataDebugMessage.debugEntryMessage(null, null);
+    mdcDataDebugMessage.debugEntryMessage(null);
 
     Optional<String> value = formatValue(uniqueCombination);
     if (!value.isPresent()) {
@@ -120,11 +115,11 @@
     }
     validateUniqueValue(type, value.get(), uniqueCombination);
 
-    mdcDataDebugMessage.debugExitMessage(null, null);
+    mdcDataDebugMessage.debugExitMessage(null);
   }
 
   private static void validateUniqueValue(String type, String value, String... uniqueCombination) {
-    mdcDataDebugMessage.debugEntryMessage(null, null);
+    mdcDataDebugMessage.debugEntryMessage(null);
 
     if (uniqueValueDao.get(new UniqueValueEntity(type, value)) != null) {
       throw new CoreException(new ErrorCode.ErrorCodeBuilder()
@@ -134,13 +129,13 @@
               uniqueCombination[uniqueCombination.length - 1])).build());
     }
 
-    mdcDataDebugMessage.debugExitMessage(null, null);
+    mdcDataDebugMessage.debugExitMessage(null);
   }
 
   private static Optional<String> formatValue(String[] uniqueCombination) {
 
 
-    mdcDataDebugMessage.debugEntryMessage(null, null);
+    mdcDataDebugMessage.debugEntryMessage(null);
 
     if (uniqueCombination == null || uniqueCombination.length == 0
         || uniqueCombination[uniqueCombination.length - 1] == null) {
@@ -150,7 +145,7 @@
     uniqueCombination[uniqueCombination.length - 1] =
         uniqueCombination[uniqueCombination.length - 1].toLowerCase();
 
-    mdcDataDebugMessage.debugExitMessage(null, null);
+    mdcDataDebugMessage.debugExitMessage(null);
     return Optional.of(CommonMethods.arrayToSeparatedString(uniqueCombination, '_'));
   }
 }
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-nosqldb-lib/openecomp-nosqldb-core/src/main/java/org/openecomp/core/nosqldb/impl/cassandra/CassandraNoSqlDbImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-nosqldb-lib/openecomp-nosqldb-core/src/main/java/org/openecomp/core/nosqldb/impl/cassandra/CassandraNoSqlDbImpl.java
index 93410bc..2172e1b 100644
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-nosqldb-lib/openecomp-nosqldb-core/src/main/java/org/openecomp/core/nosqldb/impl/cassandra/CassandraNoSqlDbImpl.java
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-nosqldb-lib/openecomp-nosqldb-core/src/main/java/org/openecomp/core/nosqldb/impl/cassandra/CassandraNoSqlDbImpl.java
@@ -20,7 +20,11 @@
 
 package org.openecomp.core.nosqldb.impl.cassandra;
 
-import com.datastax.driver.core.*;
+import com.datastax.driver.core.BoundStatement;
+import com.datastax.driver.core.Host;
+import com.datastax.driver.core.PreparedStatement;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Session;
 import com.datastax.driver.mapping.MappingManager;
 import org.openecomp.core.nosqldb.api.NoSqlDb;
 import org.openecomp.core.nosqldb.util.CassandraUtils;
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-nosqldb-lib/openecomp-nosqldb-core/src/test/java/org/openecomp/core/nosqldb/NoSqlDbTest.java b/openecomp-be/lib/openecomp-core-lib/openecomp-nosqldb-lib/openecomp-nosqldb-core/src/test/java/org/openecomp/core/nosqldb/NoSqlDbTest.java
index 5c4f951..2bab7e0 100644
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-nosqldb-lib/openecomp-nosqldb-core/src/test/java/org/openecomp/core/nosqldb/NoSqlDbTest.java
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-nosqldb-lib/openecomp-nosqldb-core/src/test/java/org/openecomp/core/nosqldb/NoSqlDbTest.java
@@ -20,14 +20,7 @@
 
 package org.openecomp.core.nosqldb;
 
-import com.datastax.driver.core.ResultSet;
-import com.datastax.driver.core.Row;
 import org.openecomp.core.nosqldb.api.NoSqlDb;
-import org.openecomp.core.nosqldb.factory.NoSqlDbFactory;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-import java.util.List;
 
 
 public class NoSqlDbTest {
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-nosqldb-lib/openecomp-nosqldb-core/src/test/java/org/openecomp/core/nosqldb/util/ConfigurationManagerTest.java b/openecomp-be/lib/openecomp-core-lib/openecomp-nosqldb-lib/openecomp-nosqldb-core/src/test/java/org/openecomp/core/nosqldb/util/ConfigurationManagerTest.java
index f8d5d2d..7a6343d 100644
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-nosqldb-lib/openecomp-nosqldb-core/src/test/java/org/openecomp/core/nosqldb/util/ConfigurationManagerTest.java
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-nosqldb-lib/openecomp-nosqldb-core/src/test/java/org/openecomp/core/nosqldb/util/ConfigurationManagerTest.java
@@ -7,7 +7,7 @@
 import java.io.IOException;
 import java.lang.reflect.Field;
 
-import static org.testng.Assert.*;
+import static org.testng.Assert.assertNotNull;
 
 /**
  * @author EVITALIY
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-session-lib/pom.xml b/openecomp-be/lib/openecomp-core-lib/openecomp-session-lib/pom.xml
new file mode 100644
index 0000000..c0618ba
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-session-lib/pom.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.openecomp.sdc.core</groupId>
+        <artifactId>openecomp-core-lib</artifactId>
+        <version>1.2.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>openecomp-session-lib</artifactId>
+
+
+    <dependencies>
+        <dependency>
+            <groupId>org.openecomp.sdc.core</groupId>
+            <artifactId>openecomp-facade-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.openecomp.sdc.core</groupId>
+            <artifactId>openecomp-facade-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+
+</project>
\ No newline at end of file
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-session-lib/src/main/java/org/openecomp/sdc/common/session/SessionContext.java b/openecomp-be/lib/openecomp-core-lib/openecomp-session-lib/src/main/java/org/openecomp/sdc/common/session/SessionContext.java
new file mode 100644
index 0000000..a1b410c
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-session-lib/src/main/java/org/openecomp/sdc/common/session/SessionContext.java
@@ -0,0 +1,8 @@
+package org.openecomp.sdc.common.session;
+
+public interface SessionContext {
+
+  User getUser();
+
+  String getTenant();
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-session-lib/src/main/java/org/openecomp/sdc/common/session/SessionContextProvider.java b/openecomp-be/lib/openecomp-core-lib/openecomp-session-lib/src/main/java/org/openecomp/sdc/common/session/SessionContextProvider.java
new file mode 100644
index 0000000..8efbbd1
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-session-lib/src/main/java/org/openecomp/sdc/common/session/SessionContextProvider.java
@@ -0,0 +1,10 @@
+package org.openecomp.sdc.common.session;
+
+public interface SessionContextProvider {
+
+  void create(String user);
+
+  SessionContext get();
+
+  void close();
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-session-lib/src/main/java/org/openecomp/sdc/common/session/SessionContextProviderFactory.java b/openecomp-be/lib/openecomp-core-lib/openecomp-session-lib/src/main/java/org/openecomp/sdc/common/session/SessionContextProviderFactory.java
new file mode 100644
index 0000000..cfa6a34
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-session-lib/src/main/java/org/openecomp/sdc/common/session/SessionContextProviderFactory.java
@@ -0,0 +1,32 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.common.session;
+
+import org.openecomp.core.factory.api.AbstractComponentFactory;
+import org.openecomp.core.factory.api.AbstractFactory;
+
+public abstract class SessionContextProviderFactory
+    extends AbstractComponentFactory<SessionContextProvider> {
+
+  public static SessionContextProviderFactory getInstance() {
+    return AbstractFactory.getInstance(SessionContextProviderFactory.class);
+  }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-session-lib/src/main/java/org/openecomp/sdc/common/session/User.java b/openecomp-be/lib/openecomp-core-lib/openecomp-session-lib/src/main/java/org/openecomp/sdc/common/session/User.java
new file mode 100644
index 0000000..5319a0b
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-session-lib/src/main/java/org/openecomp/sdc/common/session/User.java
@@ -0,0 +1,13 @@
+package org.openecomp.sdc.common.session;
+
+public class User {
+  private final String userId;
+
+  public User(String userId) {
+    this.userId = userId;
+  }
+
+  public String getUserId() {
+    return userId;
+  }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-session-lib/src/main/java/org/openecomp/sdc/common/session/impl/AsdcSessionContextProvider.java b/openecomp-be/lib/openecomp-core-lib/openecomp-session-lib/src/main/java/org/openecomp/sdc/common/session/impl/AsdcSessionContextProvider.java
new file mode 100644
index 0000000..53a40a1
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-session-lib/src/main/java/org/openecomp/sdc/common/session/impl/AsdcSessionContextProvider.java
@@ -0,0 +1,50 @@
+package org.openecomp.sdc.common.session.impl;
+
+import org.openecomp.sdc.common.session.SessionContext;
+import org.openecomp.sdc.common.session.SessionContextProvider;
+import org.openecomp.sdc.common.session.User;
+
+public class AsdcSessionContextProvider implements SessionContextProvider {
+
+  private static final ThreadLocal<String> threadUserId = new ThreadLocal<>();
+
+  @Override
+  public void create(String userId) {
+    threadUserId.set(userId);
+  }
+
+  @Override
+  public SessionContext get() {
+    if (threadUserId.get() == null) {
+      throw new RuntimeException("UserId was not set for this thread");
+    }
+
+    return new AsdcSessionContext(new User(threadUserId.get()), "dox");
+  }
+
+  @Override
+  public void close() {
+    threadUserId.remove();
+  }
+
+  private static class AsdcSessionContext implements SessionContext {
+
+    private final User user;
+    private final String tenant;
+
+    private AsdcSessionContext(User user, String tenant) {
+      this.user = user;
+      this.tenant = tenant;
+    }
+
+    @Override
+    public User getUser() {
+      return user;
+    }
+
+    @Override
+    public String getTenant() {
+      return tenant;
+    }
+  }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-session-lib/src/main/java/org/openecomp/sdc/common/session/impl/SessionContextProviderFactoryImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-session-lib/src/main/java/org/openecomp/sdc/common/session/impl/SessionContextProviderFactoryImpl.java
new file mode 100644
index 0000000..635aa5b
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-session-lib/src/main/java/org/openecomp/sdc/common/session/impl/SessionContextProviderFactoryImpl.java
@@ -0,0 +1,33 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.common.session.impl;
+
+import org.openecomp.sdc.common.session.SessionContextProvider;
+import org.openecomp.sdc.common.session.SessionContextProviderFactory;
+
+public class SessionContextProviderFactoryImpl extends SessionContextProviderFactory {
+  private static final SessionContextProvider INSTANCE = new AsdcSessionContextProvider();
+
+  @Override
+  public SessionContextProvider createInterface() {
+    return INSTANCE;
+  }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-session-lib/src/main/resources/factoryConfiguration.json b/openecomp-be/lib/openecomp-core-lib/openecomp-session-lib/src/main/resources/factoryConfiguration.json
new file mode 100644
index 0000000..cd1637a
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-session-lib/src/main/resources/factoryConfiguration.json
@@ -0,0 +1,3 @@
+{
+  "org.openecomp.sdc.common.session.SessionContextProviderFactory": "org.openecomp.sdc.common.session.impl.SessionContextProviderFactoryImpl"
+}
\ No newline at end of file
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-utilities-lib/src/main/java/org/openecomp/core/utilities/file/FileUtils.java b/openecomp-be/lib/openecomp-core-lib/openecomp-utilities-lib/src/main/java/org/openecomp/core/utilities/file/FileUtils.java
index 6ab3f8b..5a8a2db 100644
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-utilities-lib/src/main/java/org/openecomp/core/utilities/file/FileUtils.java
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-utilities-lib/src/main/java/org/openecomp/core/utilities/file/FileUtils.java
@@ -23,12 +23,9 @@
 import org.apache.commons.io.FilenameUtils;
 import org.apache.commons.io.IOUtils;
 import org.openecomp.core.utilities.json.JsonUtil;
-import org.openecomp.sdc.logging.api.Logger;
-import org.openecomp.sdc.logging.api.LoggerFactory;
 import org.openecomp.sdc.tosca.services.YamlUtil;
 
 import java.io.ByteArrayInputStream;
-import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-utilities-lib/src/test/java/org/openecomp/core/utilities/file/FileContentHandlerTest.java b/openecomp-be/lib/openecomp-core-lib/openecomp-utilities-lib/src/test/java/org/openecomp/core/utilities/file/FileContentHandlerTest.java
index 527ba22..be0686e 100644
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-utilities-lib/src/test/java/org/openecomp/core/utilities/file/FileContentHandlerTest.java
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-utilities-lib/src/test/java/org/openecomp/core/utilities/file/FileContentHandlerTest.java
@@ -6,7 +6,9 @@
 import java.util.Arrays;
 import java.util.Optional;
 
-import static org.testng.Assert.*;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
 
 /**
  * @author EVITALIY
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-api/pom.xml b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-api/pom.xml
index 538a7fb..ee59b5b 100644
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-api/pom.xml
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-api/pom.xml
@@ -20,6 +20,16 @@
         </dependency>
         <dependency>
             <groupId>org.openecomp.sdc.core</groupId>
+            <artifactId>openecomp-session-lib</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.openecomp.sdc</groupId>
+            <artifactId>openecomp-sdc-versioning-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.openecomp.sdc.core</groupId>
             <artifactId>openecomp-facade-api</artifactId>
             <version>${project.version}</version>
         </dependency>
@@ -43,6 +53,11 @@
             <artifactId>commons-lang3</artifactId>
             <version>3.4</version>
         </dependency>
+        <dependency>
+            <groupId>com.amdocs.zusammen</groupId>
+            <artifactId>zusammen-datatypes</artifactId>
+            <version>${zusammen.version}</version>
+        </dependency>
     </dependencies>
 
 
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-api/src/main/java/org/openecomp/convertor/ElementConvertor.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-api/src/main/java/org/openecomp/convertor/ElementConvertor.java
new file mode 100644
index 0000000..68c7098
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-api/src/main/java/org/openecomp/convertor/ElementConvertor.java
@@ -0,0 +1,37 @@
+package org.openecomp.convertor;
+
+import com.amdocs.zusammen.adaptor.inbound.api.types.item.Element;
+import com.amdocs.zusammen.adaptor.inbound.api.types.item.ElementInfo;
+import com.amdocs.zusammen.datatypes.item.Item;
+import com.amdocs.zusammen.datatypes.item.ItemVersion;
+import org.openecomp.sdc.datatypes.model.ElementType;
+import org.openecomp.types.ElementPropertyName;
+
+public abstract class ElementConvertor<T> {
+
+  public static ElementType getElementType(Element element) {
+    return ElementType
+        .valueOf(element.getInfo().getProperty(ElementPropertyName.elementType.name()));
+  }
+
+  public static String getElementName(Element element) {
+    return element.getInfo().getName();
+  }
+
+
+  abstract public T convert(Element element);
+
+  public T convert( ElementInfo elementInfo) {
+    throw new UnsupportedOperationException("convert elementInfo item is not supported ");
+  }
+
+
+  public T convert( Item item) {
+    throw new UnsupportedOperationException("convert from item is not supported ");
+  }
+
+
+  public T convert( ItemVersion itemVersion) {
+    throw new UnsupportedOperationException("convert from itemVersion is not supported ");
+  }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-api/src/main/java/org/openecomp/core/zusammen/api/ZusammenAdaptor.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-api/src/main/java/org/openecomp/core/zusammen/api/ZusammenAdaptor.java
index 2ba447f..35c07cb 100644
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-api/src/main/java/org/openecomp/core/zusammen/api/ZusammenAdaptor.java
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-api/src/main/java/org/openecomp/core/zusammen/api/ZusammenAdaptor.java
@@ -1,7 +1,9 @@
 package org.openecomp.core.zusammen.api;
 
 import com.amdocs.zusammen.adaptor.inbound.api.types.item.Element;
+import com.amdocs.zusammen.adaptor.inbound.api.types.item.ElementConflict;
 import com.amdocs.zusammen.adaptor.inbound.api.types.item.ElementInfo;
+import com.amdocs.zusammen.adaptor.inbound.api.types.item.ItemVersionConflict;
 import com.amdocs.zusammen.adaptor.inbound.api.types.item.ZusammenElement;
 import com.amdocs.zusammen.commons.health.data.HealthInfo;
 import com.amdocs.zusammen.datatypes.Id;
@@ -11,31 +13,53 @@
 import com.amdocs.zusammen.datatypes.item.Item;
 import com.amdocs.zusammen.datatypes.item.ItemVersion;
 import com.amdocs.zusammen.datatypes.item.ItemVersionData;
+import com.amdocs.zusammen.datatypes.item.ItemVersionStatus;
+import com.amdocs.zusammen.datatypes.item.Resolution;
 import com.amdocs.zusammen.datatypes.itemversion.Tag;
+import org.openecomp.sdc.versioning.dao.types.Revision;
 
 import java.util.Collection;
+import java.util.List;
 import java.util.Optional;
 
 public interface ZusammenAdaptor {
 
   Collection<Item> listItems(SessionContext context);
 
+  Item getItem(SessionContext context, Id itemId);
+
   Id createItem(SessionContext context, Info info);
 
   void updateItem(SessionContext context, Id itemId, Info info);
 
-  // TODO: 4/4/2017 fix this workaround when versionId will be recieved from UI
+  // TODO: 4/4/2017 remove this workaround when versionId will be recieved from UI
   Optional<ItemVersion> getFirstVersion(SessionContext context, Id itemId);
 
+  Collection<ItemVersion> listPublicVersions(SessionContext context, Id itemId);
+
+  ItemVersion getPublicVersion(SessionContext context, Id itemId, Id versionId);
+
   Id createVersion(SessionContext context, Id itemId, Id baseVersionId,
                    ItemVersionData itemVersionData);
 
   void updateVersion(SessionContext context, Id itemId, Id versionId,
                      ItemVersionData itemVersionData);
 
+  ItemVersion getVersion(SessionContext context, Id itemId, Id versionId);
+
+  ItemVersionStatus getVersionStatus(SessionContext context, Id itemId, Id versionId);
+
+  ItemVersionConflict getVersionConflict(SessionContext context, Id itemId, Id versionId);
+
   void tagVersion(SessionContext context, Id itemId, Id versionId, Tag tag);
 
-  void resetVersionHistory(SessionContext context, Id itemId, Id versionId, String changeRef);
+  void resetVersionHistory(SessionContext context, Id itemId, Id versionId, String version);
+
+  void publishVersion(SessionContext context, Id itemId, Id versionId, String message);
+
+  void syncVersion(SessionContext context, Id itemId, Id versionId);
+
+  void forceSyncVersion(SessionContext context, Id itemId, Id versionId);
 
   Optional<ElementInfo> getElementInfo(SessionContext context, ElementContext elementContext,
                                        Id elementId);
@@ -43,38 +67,39 @@
   Optional<Element> getElement(SessionContext context, ElementContext elementContext,
                                String elementId); // TODO: 4/3/2017 change to Id
 
-  Optional<Element> getElementByName(
-      SessionContext context, ElementContext elementContext, Id parentElementId,
-      String elementName);
+  Optional<Element> getElementByName(SessionContext context, ElementContext elementContext,
+                                     Id parentElementId, String elementName);
 
-  Collection<ElementInfo> listElements(SessionContext context,
-                                       ElementContext elementContext,
+  Collection<ElementInfo> listElements(SessionContext context, ElementContext elementContext,
                                        Id parentElementId);
 
-  Collection<Element> listElementData(SessionContext context,
-                                      ElementContext elementContext,
+  Collection<Element> listElementData(SessionContext context, ElementContext elementContext,
                                       Id parentElementId);
 
   /**
-   * Lists the sub elements of the element named <elementName> which is a sub element of <parentElementId>
-   * @param context
-   * @param elementContext
-   * @param parentElementId
-   * @param elementName
-   * @return
+   * Lists the sub elements of the element named elementName which is a sub element of
+   * parentElementId
    */
-  Collection<ElementInfo> listElementsByName(
-      SessionContext context, ElementContext elementContext, Id parentElementId,
-      String elementName);
+  Collection<ElementInfo> listElementsByName(SessionContext context, ElementContext elementContext,
+                                             Id parentElementId, String elementName);
 
-  Optional<ElementInfo> getElementInfoByName(
-      SessionContext context, ElementContext elementContext, Id parentElementId,
-      String elementName);
+  Optional<ElementInfo> getElementInfoByName(SessionContext context, ElementContext elementContext,
+                                             Id parentElementId, String elementName);
 
-  Optional<Element> saveElement(SessionContext context, ElementContext elementContext,
-                                ZusammenElement element, String message);
+  Optional<ElementConflict> getElementConflict(SessionContext context,
+                                               ElementContext elementContext, Id elementId);
+
+  Element saveElement(SessionContext context, ElementContext elementContext,
+                      ZusammenElement element, String message);
+
+  void resolveElementConflict(SessionContext context, ElementContext elementContext,
+                              ZusammenElement element, Resolution resolution);
 
   Collection<HealthInfo> checkHealth(SessionContext context);
 
-  String getVersion(SessionContext sessionContext);
+  String getVersion(SessionContext context);
+
+  void revert(SessionContext sessionContext, String itemId, String versionId, String revisionId);
+
+  List<Revision> listRevisions(SessionContext sessionContext, String itemId, String versionId);
 }
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-api/src/main/java/org/openecomp/core/zusammen/api/ZusammenUtil.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-api/src/main/java/org/openecomp/core/zusammen/api/ZusammenUtil.java
index 3df6151..623f958 100644
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-api/src/main/java/org/openecomp/core/zusammen/api/ZusammenUtil.java
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-api/src/main/java/org/openecomp/core/zusammen/api/ZusammenUtil.java
@@ -1,40 +1,40 @@
 package org.openecomp.core.zusammen.api;
 
 import com.amdocs.zusammen.adaptor.inbound.api.types.item.ZusammenElement;
+import com.amdocs.zusammen.datatypes.Id;
 import com.amdocs.zusammen.datatypes.SessionContext;
 import com.amdocs.zusammen.datatypes.UserInfo;
 import com.amdocs.zusammen.datatypes.item.Action;
 import com.amdocs.zusammen.datatypes.item.Info;
-import com.amdocs.zusammen.datatypes.item.ItemVersionData;
+import org.openecomp.sdc.common.session.SessionContextProviderFactory;
+import org.openecomp.sdc.datatypes.model.ElementType;
+import org.openecomp.types.ElementPropertyName;
 
 public class ZusammenUtil {
-  // TODO: 3/19/2017 add user and tenant args
+
   public static SessionContext createSessionContext() {
+    org.openecomp.sdc.common.session.SessionContext asdcSessionContext =
+        SessionContextProviderFactory.getInstance().createInterface().get();
+
     SessionContext sessionContext = new SessionContext();
-    sessionContext.setUser(new UserInfo("GLOBAL_USER"));
-    sessionContext.setTenant("dox");
+    sessionContext.setUser(new UserInfo(asdcSessionContext.getUser().getUserId()));
+    sessionContext.setTenant(asdcSessionContext.getTenant());
     return sessionContext;
   }
 
-  public static ZusammenElement buildStructuralElement(String structureElementName,
-                                                       Action action) {
-    ZusammenElement element = new ZusammenElement();
+  public static ZusammenElement buildStructuralElement(ElementType elementType, Action action) {
+    ZusammenElement element = buildElement(null, action);
     Info info = new Info();
-    info.setName(structureElementName);
+    info.setName(elementType.name());
+    info.addProperty(ElementPropertyName.elementType.name(), elementType.name());
     element.setInfo(info);
-    if (action != null) {
-      element.setAction(action);
-    }
     return element;
   }
 
-  // TODO: 4/24/2017 remove upon working with more than one single version
-  public static ItemVersionData createFirstVersionData() {
-    Info info = new Info();
-    info.setName("main version");
-    ItemVersionData itemVersionData = new ItemVersionData();
-    itemVersionData.setInfo(info);
-    return itemVersionData;
+  public static ZusammenElement buildElement(Id elementId, Action action) {
+    ZusammenElement element = new ZusammenElement();
+    element.setElementId(elementId);
+    element.setAction(action);
+    return element;
   }
-
 }
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-api/src/main/java/org/openecomp/types/AsdcElement.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-api/src/main/java/org/openecomp/types/AsdcElement.java
new file mode 100644
index 0000000..ae9c1fc
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-api/src/main/java/org/openecomp/types/AsdcElement.java
@@ -0,0 +1,131 @@
+package org.openecomp.types;
+
+import com.amdocs.zusammen.adaptor.inbound.api.types.item.Element;
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.item.Action;
+import com.amdocs.zusammen.datatypes.item.Info;
+import com.amdocs.zusammen.datatypes.item.Relation;
+import com.amdocs.zusammen.utils.fileutils.FileUtils;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+
+public class AsdcElement implements Element {
+
+  private String type;
+  private String name;
+  private String description;
+
+  private Map<String, Object> properties;
+  private byte[] data;
+  private Collection<Relation> relations;
+  private Collection<Element> subElements = new ArrayList<>();
+  private Action action;
+  private Id elementId;
+
+  @Override
+  public Action getAction() {
+    return this.action;
+  }
+
+  @Override
+  public Id getElementId() {
+    return this.elementId;
+  }
+
+  @Override
+  public Info getInfo() {
+    Info info = new Info();
+    info.setProperties(this.properties);
+    info.addProperty(ElementPropertyName.elementType.name(), this.type != null ? this.type : this.name);
+    info.setName(this.name);
+    info.setDescription(this.description);
+
+    return info;
+  }
+
+  @Override
+  public Collection<Relation> getRelations() {
+    return this.relations;
+  }
+
+  @Override
+  public InputStream getData() {
+    return FileUtils.toInputStream(this.data);
+  }
+
+  @Override
+  public InputStream getSearchableData() {
+    return null;
+  }
+
+  @Override
+  public InputStream getVisualization() {
+    return null;
+  }
+
+
+  @Override
+  public Collection<Element> getSubElements() {
+    return this.subElements;
+  }
+
+  public void setElementId(Id elementId) {
+    this.elementId = elementId;
+  }
+
+  public void setData(InputStream data) {
+    this.data = FileUtils.toByteArray(data);
+  }
+
+  public void setRelations(Collection<Relation> relations) {
+    this.relations = relations;
+  }
+
+  public void setSubElements(Collection<Element> subElements) {
+    this.subElements = subElements;
+  }
+
+  public void setAction(Action action) {
+    this.action = action;
+  }
+
+  public AsdcElement addSubElement(Element element) {
+    this.subElements.add(element);
+    return this;
+  }
+
+  public String getType() {
+    return type;
+  }
+
+  public void setType(String type) {
+    this.type = type;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public void setName(String name) {
+    this.name = name;
+  }
+
+  public String getDescription() {
+    return description;
+  }
+
+  public void setDescription(String description) {
+    this.description = description;
+  }
+
+  public Map<String, Object> getProperties() {
+    return properties;
+  }
+
+  public void setProperties(Map<String, Object> properties) {
+    this.properties = properties;
+  }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-api/src/main/java/org/openecomp/types/ElementPropertyName.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-api/src/main/java/org/openecomp/types/ElementPropertyName.java
new file mode 100644
index 0000000..ddbef7d
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-api/src/main/java/org/openecomp/types/ElementPropertyName.java
@@ -0,0 +1,6 @@
+package org.openecomp.types;
+
+public enum ElementPropertyName {
+  elementType,
+  compositionData
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-core/src/main/java/org/openecomp/core/zusammen/db/ZusammenConnector.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-core/src/main/java/org/openecomp/core/zusammen/db/ZusammenConnector.java
index 6381b2e..9005bb8 100644
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-core/src/main/java/org/openecomp/core/zusammen/db/ZusammenConnector.java
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-core/src/main/java/org/openecomp/core/zusammen/db/ZusammenConnector.java
@@ -1,7 +1,9 @@
 package org.openecomp.core.zusammen.db;
 
 import com.amdocs.zusammen.adaptor.inbound.api.types.item.Element;
+import com.amdocs.zusammen.adaptor.inbound.api.types.item.ElementConflict;
 import com.amdocs.zusammen.adaptor.inbound.api.types.item.ElementInfo;
+import com.amdocs.zusammen.adaptor.inbound.api.types.item.ItemVersionConflict;
 import com.amdocs.zusammen.adaptor.inbound.api.types.item.ZusammenElement;
 import com.amdocs.zusammen.commons.health.data.HealthInfo;
 import com.amdocs.zusammen.datatypes.Id;
@@ -11,22 +13,31 @@
 import com.amdocs.zusammen.datatypes.item.Item;
 import com.amdocs.zusammen.datatypes.item.ItemVersion;
 import com.amdocs.zusammen.datatypes.item.ItemVersionData;
+import com.amdocs.zusammen.datatypes.item.ItemVersionStatus;
+import com.amdocs.zusammen.datatypes.item.Resolution;
+import com.amdocs.zusammen.datatypes.itemversion.ItemVersionRevisions;
 import com.amdocs.zusammen.datatypes.itemversion.Tag;
-import com.amdocs.zusammen.datatypes.response.Response;
 
 import java.util.Collection;
-import java.util.Optional;
 
 public interface ZusammenConnector {
 
+  Collection<HealthInfo> checkHealth(SessionContext sessionContext);
+
+  String getVersion(SessionContext sessionContext);
+
   Collection<Item> listItems(SessionContext context);
 
+  Item getItem(SessionContext context, Id itemId);
+
   Id createItem(SessionContext context, Info info);
 
   void updateItem(SessionContext context, Id itemId, Info info);
 
 
-  Collection<ItemVersion> listVersions(SessionContext context, Id itemId);
+  Collection<ItemVersion> listPublicVersions(SessionContext context, Id itemId);
+
+  ItemVersion getPublicVersion(SessionContext context, Id itemId, Id versionId);
 
   Id createVersion(SessionContext context, Id itemId, Id baseVersionId,
                    ItemVersionData itemVersionData);
@@ -34,23 +45,42 @@
   void updateVersion(SessionContext context, Id itemId, Id versionId,
                      ItemVersionData itemVersionData);
 
+  ItemVersion getVersion(SessionContext context, Id itemId, Id versionId);
+
+  ItemVersionStatus getVersionStatus(SessionContext context, Id itemId, Id versionId);
+
   void tagVersion(SessionContext context, Id itemId, Id versionId, Tag tag);
 
-  void resetVersionHistory(SessionContext context, Id itemId, Id versionId, String changeRef);
+  void resetVersionRevision(SessionContext context, Id itemId, Id versionId, Id revisionId);
+
+  void revertVersionRevision(SessionContext context, Id itemId, Id versionId, Id revisionId);
+
+  ItemVersionRevisions listVersionRevisions(SessionContext context, Id itemId, Id versionId);
+
+  void publishVersion(SessionContext context, Id itemId, Id versionId, String message);
+
+  void syncVersion(SessionContext context, Id itemId, Id versionId);
+
+  void forceSyncVersion(SessionContext context, Id itemId, Id versionId);
+
+  ItemVersionConflict getVersionConflict(SessionContext context, Id itemId, Id versionId);
 
 
   Collection<ElementInfo> listElements(SessionContext context, ElementContext elementContext,
                                        Id parentElementId);
 
-  Response<ElementInfo> getElementInfo(SessionContext context, ElementContext elementContext, Id
-      elementId);
+  ElementInfo getElementInfo(SessionContext context, ElementContext elementContext, Id elementId);
 
-  Response<Element> getElement(SessionContext context, ElementContext elementContext, Id elementId);
+  Element getElement(SessionContext context, ElementContext elementContext, Id elementId);
 
-  Optional<Element> saveElement(SessionContext context, ElementContext elementContext,
-                                ZusammenElement element, String message);
+  ElementConflict getElementConflict(SessionContext context, ElementContext elementContext,
+                                     Id elementId);
 
-  Collection<HealthInfo> checkHealth(SessionContext sessionContext);
+  Element saveElement(SessionContext context, ElementContext elementContext,
+                      ZusammenElement element, String message);
 
-  String getVersion(SessionContext sessionContext);
+  void resolveElementConflict(SessionContext context, ElementContext elementContext,
+                              ZusammenElement element, Resolution resolution);
+
+  void resetVersionHistory(SessionContext context, Id itemId, Id versionId, String changeRef);
 }
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-core/src/main/java/org/openecomp/core/zusammen/db/impl/ZusammenConnectorImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-core/src/main/java/org/openecomp/core/zusammen/db/impl/ZusammenConnectorImpl.java
index deb5ffd..1d387b9 100644
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-core/src/main/java/org/openecomp/core/zusammen/db/impl/ZusammenConnectorImpl.java
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-core/src/main/java/org/openecomp/core/zusammen/db/impl/ZusammenConnectorImpl.java
@@ -1,11 +1,14 @@
 package org.openecomp.core.zusammen.db.impl;
 
+import com.amdocs.zusammen.adaptor.inbound.api.health.HealthAdaptorFactory;
 import com.amdocs.zusammen.adaptor.inbound.api.item.ElementAdaptorFactory;
 import com.amdocs.zusammen.adaptor.inbound.api.item.ItemAdaptorFactory;
 import com.amdocs.zusammen.adaptor.inbound.api.item.ItemVersionAdaptorFactory;
-import com.amdocs.zusammen.adaptor.inbound.api.health.HealthAdaptorFactory;
 import com.amdocs.zusammen.adaptor.inbound.api.types.item.Element;
+import com.amdocs.zusammen.adaptor.inbound.api.types.item.ElementConflict;
 import com.amdocs.zusammen.adaptor.inbound.api.types.item.ElementInfo;
+import com.amdocs.zusammen.adaptor.inbound.api.types.item.ItemVersionConflict;
+import com.amdocs.zusammen.adaptor.inbound.api.types.item.MergeResult;
 import com.amdocs.zusammen.adaptor.inbound.api.types.item.ZusammenElement;
 import com.amdocs.zusammen.commons.health.data.HealthInfo;
 import com.amdocs.zusammen.datatypes.Id;
@@ -16,6 +19,9 @@
 import com.amdocs.zusammen.datatypes.item.Item;
 import com.amdocs.zusammen.datatypes.item.ItemVersion;
 import com.amdocs.zusammen.datatypes.item.ItemVersionData;
+import com.amdocs.zusammen.datatypes.item.ItemVersionStatus;
+import com.amdocs.zusammen.datatypes.item.Resolution;
+import com.amdocs.zusammen.datatypes.itemversion.ItemVersionRevisions;
 import com.amdocs.zusammen.datatypes.itemversion.Tag;
 import com.amdocs.zusammen.datatypes.response.Response;
 import com.amdocs.zusammen.datatypes.response.ReturnCode;
@@ -28,14 +34,18 @@
 import org.openecomp.sdc.logging.types.LoggerErrorCode;
 
 import java.util.Collection;
-import java.util.Optional;
 
 public class ZusammenConnectorImpl implements ZusammenConnector {
 
+  private static final String GET_ELEMENT_ERR_MSG =
+      "Failed to get element. Item Id: %s, version Id: %s, element Id: %s message: %s";
+  private static final String GET_ELEMENT_IN_REV_ERR_MSG =
+      "Failed to get element. Item Id: %s, version Id: %s, revision Id: %s, element Id: %s message: %s";
   private ItemAdaptorFactory itemAdaptorFactory;
   private ItemVersionAdaptorFactory versionAdaptorFactory;
   private ElementAdaptorFactory elementAdaptorFactory;
   private HealthAdaptorFactory healthAdaptorFactory;
+
   public ZusammenConnectorImpl(
       ItemAdaptorFactory itemAdaptorFactory,
       ItemVersionAdaptorFactory versionAdaptorFactory,
@@ -69,14 +79,23 @@
   }
 
   @Override
+  public Item getItem(SessionContext context, Id itemId) {
+    Response<Item> response = itemAdaptorFactory.createInterface(context).get(context, itemId);
+    if (!response.isSuccessful()) {
+      throw new RuntimeException(
+          "Failed to get Item. message:" + response.getReturnCode().toString());
+    }
+    return response.getValue();
+  }
+
+  @Override
   public Id createItem(SessionContext context, Info info) {
     Response<Id> response = itemAdaptorFactory.createInterface(context).create(context, info);
-    if (response.isSuccessful()) {
-      return response.getValue();
-    } else {
+    if (!response.isSuccessful()) {
       throw new RuntimeException(
-          "failed to create Item. message:" + response.getReturnCode().toString());
+          "Failed to create Item. message:" + response.getReturnCode().toString());
     }
+    return response.getValue();
   }
 
   @Override
@@ -91,18 +110,30 @@
   }
 
   @Override
-  public Collection<ItemVersion> listVersions(SessionContext context, Id itemId) {
+  public Collection<ItemVersion> listPublicVersions(SessionContext context, Id itemId) {
     Response<Collection<ItemVersion>> versions =
-        versionAdaptorFactory.createInterface(context).list(context, Space.PRIVATE, itemId);
+        versionAdaptorFactory.createInterface(context).list(context, Space.PUBLIC, itemId);
     if (!versions.isSuccessful()) {
       logErrorMessageToMdc(ItemElementLoggerTargetServiceName.ITEM_VERSION_RETRIEVAL, versions
           .getReturnCode());
-      throw new RuntimeException(versions.getReturnCode().toString()); // TODO: 3/26/2017
+      throw new RuntimeException(versions.getReturnCode().toString());
     }
     return versions.getValue();
   }
 
   @Override
+  public ItemVersion getPublicVersion(SessionContext context, Id itemId, Id versionId) {
+    Response<ItemVersion> response = versionAdaptorFactory.createInterface(context)
+        .get(context, Space.PUBLIC, itemId, versionId);
+    if (!response.isSuccessful()) {
+      throw new RuntimeException(
+          String.format("failed to get public Item Version. ItemId: %s, versionId: %s, message: %s",
+              itemId.getValue(), versionId.getValue(), response.getReturnCode().toString()));
+    }
+    return response.getValue();
+  }
+
+  @Override
   public Id createVersion(SessionContext context, Id itemId, Id baseVersionId,
                           ItemVersionData itemVersionData) {
     Response<Id> response = versionAdaptorFactory.createInterface(context).create(context, itemId,
@@ -110,10 +141,9 @@
     if (response.isSuccessful()) {
       return response.getValue();
     } else {
-      throw new RuntimeException("failed to create Item Version. ItemId:" + itemId + " based " +
-          "on:" + baseVersionId +
-          " message:" + response
-          .getReturnCode().toString());
+      throw new RuntimeException(String.format(
+          "failed to create Item Version. ItemId: %s, base versionId: %s, message: %s",
+          itemId.getValue(), baseVersionId.getValue(), response.getReturnCode().toString()));
     }
   }
 
@@ -124,77 +154,233 @@
         .update(context, itemId, versionId, itemVersionData);
     if (!response.isSuccessful()) {
       throw new RuntimeException(
-          String.format("failed to create Item Version. ItemId: %s, versionId: %s, message: %s",
+          String.format("failed to update Item Version. ItemId: %s, versionId: %s, message: %s",
               itemId.getValue(), versionId.getValue(), response.getReturnCode().toString()));
     }
   }
 
   @Override
+  public ItemVersion getVersion(SessionContext context, Id itemId, Id versionId) {
+    Response<ItemVersion> response = versionAdaptorFactory.createInterface(context)
+        .get(context, Space.PRIVATE, itemId, versionId);
+    if (!response.isSuccessful()) {
+      throw new RuntimeException(
+          String.format("failed to get Item Version. ItemId: %s, versionId: %s, message: %s",
+              itemId.getValue(), versionId.getValue(), response.getReturnCode().toString()));
+    }
+    return response.getValue();
+  }
+
+  @Override
+  public ItemVersionStatus getVersionStatus(SessionContext context, Id itemId, Id versionId) {
+    Response<ItemVersionStatus> response =
+        versionAdaptorFactory.createInterface(context).getStatus(context, itemId, versionId);
+    if (!response.isSuccessful()) {
+      throw new RuntimeException(
+          String.format("failed to get Item Version status. ItemId: %s, versionId: %s, message: %s",
+              itemId.getValue(), versionId.getValue(), response.getReturnCode().toString()));
+    }
+    return response.getValue();
+  }
+
+  @Override
   public void tagVersion(SessionContext context, Id itemId, Id versionId, Tag tag) {
     Response<Void> response = versionAdaptorFactory.createInterface(context)
         .tag(context, itemId, versionId, null, tag);
     if (!response.isSuccessful()) {
       throw new RuntimeException(String.format(
           "failed to tag Item Version with tag %s. ItemId: %s, versionId: %s, message: %s",
-          tag.getName(), itemId.getValue(), versionId.getValue(), response.getReturnCode()
-              .getMessage()));
+          tag.getName(), itemId.getValue(), versionId.getValue(),
+          response.getReturnCode().toString()));
     }
   }
 
   @Override
-  public void resetVersionHistory(SessionContext context, Id itemId, Id versionId,
-                                  String changeRef) {
+  public void resetVersionRevision(SessionContext context, Id itemId, Id versionId,
+                                   Id revisionId) {
     Response<Void> response = versionAdaptorFactory.createInterface(context)
-        .resetHistory(context, itemId, versionId, changeRef);
+        .resetRevision(context, itemId, versionId, revisionId);
     if (!response.isSuccessful()) {
       throw new RuntimeException(String.format(
-          "failed to reset Item Version back to %s. ItemId: %s, versionId: %s, message: %s",
-          changeRef, itemId.getValue(), versionId.getValue(),
+          "failed to reset Item Version back to revision: %s. ItemId: %s, versionId: %s, message:" +
+              " %s",
+          revisionId.getValue(), itemId.getValue(), versionId.getValue(),
           response.getReturnCode().toString()));
     }
   }
 
   @Override
+  public void revertVersionRevision(SessionContext context, Id itemId, Id versionId,
+                                    Id revisionId) {
+    Response<Void> response = versionAdaptorFactory.createInterface(context)
+        .revertRevision(context, itemId, versionId, revisionId);
+    if (!response.isSuccessful()) {
+      throw new RuntimeException(String.format(
+          "failed to revert Item Version back to revision: %s. ItemId: %s, versionId: %s, " +
+              "message: %s",
+          revisionId.getValue(), itemId.getValue(), versionId.getValue(),
+          response.getReturnCode().toString()));
+    }
+  }
+
+  @Override
+  public ItemVersionRevisions listVersionRevisions(SessionContext context, Id itemId,
+                                                   Id versionId) {
+    Response<ItemVersionRevisions> response =
+        versionAdaptorFactory.createInterface(context)
+            .listRevisions(context, itemId, versionId);
+    if (!response.isSuccessful()) {
+      throw new RuntimeException(String.format(
+          "failed to list revisions of Item Version. ItemId: %s, versionId: %s, message: %s",
+          itemId.getValue(), versionId.getValue(), response.getReturnCode().toString()));
+    }
+    return response.getValue();
+  }
+
+
+  @Override
+  public void publishVersion(SessionContext context, Id itemId, Id versionId, String message) {
+    Response<Void> response =
+        versionAdaptorFactory.createInterface(context).publish(context, itemId, versionId, message);
+    if (!response.isSuccessful()) {
+      throw new RuntimeException(String.format(
+          "failed to publish item Version. ItemId: %s, versionId: %s, message: %s",
+          itemId.getValue(), versionId.getValue(), response.getReturnCode().toString()));
+    }
+  }
+
+  @Override
+  public void syncVersion(SessionContext context, Id itemId, Id versionId) {
+    Response<MergeResult> response =
+        versionAdaptorFactory.createInterface(context).sync(context, itemId, versionId);
+    if (!response.isSuccessful()) {
+      throw new RuntimeException(String.format(
+          "failed to sync item Version. ItemId: %s, versionId: %s, message: %s",
+          itemId.getValue(), versionId.getValue(), response.getReturnCode().toString()));
+    }
+  }
+
+  @Override
+  public void forceSyncVersion(SessionContext context, Id itemId, Id versionId) {
+    Response<MergeResult> response =
+        versionAdaptorFactory.createInterface(context).forceSync(context, itemId, versionId);
+    if (!response.isSuccessful()) {
+      throw new RuntimeException(String.format(
+          "failed to force sync item Version. ItemId: %s, versionId: %s, message: %s",
+          itemId.getValue(), versionId.getValue(), response.getReturnCode().toString()));
+    }
+  }
+
+  @Override
+  public ItemVersionConflict getVersionConflict(SessionContext context, Id itemId, Id versionId) {
+    Response<ItemVersionConflict> response =
+        versionAdaptorFactory.createInterface(context).getConflict(context, itemId, versionId);
+    if (!response.isSuccessful()) {
+      throw new RuntimeException(String
+          .format("failed to get Item Version conflict. ItemId: %s, versionId: %s, message: %s",
+              itemId.getValue(), versionId.getValue(), response.getReturnCode().toString()));
+    }
+    return response.getValue();
+  }
+
+  @Override
   public Collection<ElementInfo> listElements(SessionContext context,
                                               ElementContext elementContext,
                                               Id parentElementId) {
-    Response<Collection<ElementInfo>> elementInfosResponse = elementAdaptorFactory
+    Response<Collection<ElementInfo>> response = elementAdaptorFactory
         .createInterface(context).list(context, elementContext, parentElementId);
-    if (elementInfosResponse.isSuccessful()) {
-      return elementInfosResponse.getValue();
+    if (response.isSuccessful()) {
+      return response.getValue();
     } else {
       logErrorMessageToMdc(ItemElementLoggerTargetServiceName.ELEMENT_GET_BY_PROPERTY,
-          elementInfosResponse.getReturnCode());
-      throw new RuntimeException(elementInfosResponse.getReturnCode().toString());
+          response.getReturnCode());
+      throw new RuntimeException(response.getReturnCode().toString());
     }
   }
 
-  @Override
-  public Response<ElementInfo> getElementInfo(SessionContext context, ElementContext elementContext,
-                                              Id elementId) {
-    return elementAdaptorFactory.createInterface(context)
-        .getInfo(context, elementContext, elementId);
-  }
-
 
   @Override
-  public Response<Element> getElement(SessionContext context, ElementContext elementContext,
-                                      Id elementId) {
-    return elementAdaptorFactory.createInterface(context).get(context, elementContext, elementId);
+  public ElementInfo getElementInfo(SessionContext context, ElementContext elementContext,
+                                    Id elementId) {
+    Response<ElementInfo> response =
+        elementAdaptorFactory.createInterface(context).getInfo(context, elementContext, elementId);
+    if (!response.isSuccessful()) {
+      throw buildGetElementException(elementContext, elementId,
+          response.getReturnCode().toString());
+
+    }
+    return response.getValue();
   }
 
   @Override
-  public Optional<Element> saveElement(SessionContext context, ElementContext elementContext,
-                                       ZusammenElement element, String message) {
+  public Element getElement(SessionContext context, ElementContext elementContext,
+                            Id elementId) {
+    Response<Element> response =
+        elementAdaptorFactory.createInterface(context).get(context, elementContext, elementId);
+    if (!response.isSuccessful()) {
+      throw buildGetElementException(elementContext, elementId,
+          response.getReturnCode().toString());
+    }
+    return response.getValue();
+  }
+
+  @Override
+  public ElementConflict getElementConflict(SessionContext context, ElementContext elementContext,
+                                            Id elementId) {
+    Response<ElementConflict> response = elementAdaptorFactory.createInterface(context)
+        .getConflict(context, elementContext, elementId);
+    if (!response.isSuccessful()) {
+      throw new RuntimeException(String.format(
+          "Failed to get element conflict. Item Id: %s, version Id: %s, element Id: %s message: %s",
+          elementContext.getItemId().getValue(), elementContext.getVersionId().getValue(),
+          elementId.getValue(), response.getReturnCode().toString()));
+    }
+    return response.getValue();
+  }
+
+  @Override
+  public Element saveElement(SessionContext context, ElementContext elementContext,
+                             ZusammenElement element, String message) {
     Response<Element> response = elementAdaptorFactory.createInterface(context)
         .save(context, elementContext, element, message);
     if (!response.isSuccessful()) {
       throw new RuntimeException(String
-          .format("Failed to save element %s. ItemId: %s, versionId: %s, message: %s",
+          .format("Failed to create element %s. ItemId: %s, versionId: %s, message: %s",
               element.getElementId().getValue(), elementContext.getItemId().getValue(),
               elementContext.getVersionId().getValue(), response.getReturnCode().toString()));
     }
-    return Optional.of(response.getValue());
+    return response.getValue();
+  }
+
+  @Override
+  public void resolveElementConflict(SessionContext context, ElementContext elementContext,
+                                     ZusammenElement element,
+                                     Resolution resolution) {
+    Response<Void> response = elementAdaptorFactory.createInterface(context)
+        .resolveConflict(context, elementContext, element, resolution);
+    if (!response.isSuccessful()) {
+      throw new RuntimeException(
+          "Failed to resolve conflict. message:" + response.getReturnCode().toString());
+    }
+  }
+
+  @Override
+  public void resetVersionHistory(SessionContext context, Id itemId, Id versionId,
+                                  String revision_id) {
+
+  }
+
+  private RuntimeException buildGetElementException(ElementContext elementContext, Id elementId,
+                                                    String zusammenErrorMessage) {
+    if (elementContext.getRevisionId() == null) {
+      return new RuntimeException(String.format(GET_ELEMENT_ERR_MSG,
+          elementContext.getItemId().getValue(), elementContext.getVersionId().getValue(),
+          elementId.getValue(), zusammenErrorMessage));
+    }
+    return new RuntimeException(String.format(GET_ELEMENT_IN_REV_ERR_MSG,
+        elementContext.getItemId().getValue(), elementContext.getVersionId().getValue(),
+        elementContext.getRevisionId().getValue(),
+        elementId.getValue(), zusammenErrorMessage));
   }
 
   private void logErrorMessageToMdc(ItemElementLoggerTargetServiceName
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-core/src/main/java/org/openecomp/core/zusammen/impl/ZusammenAdaptorImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-core/src/main/java/org/openecomp/core/zusammen/impl/ZusammenAdaptorImpl.java
index 41ce028..9bdbfd6 100644
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-core/src/main/java/org/openecomp/core/zusammen/impl/ZusammenAdaptorImpl.java
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-core/src/main/java/org/openecomp/core/zusammen/impl/ZusammenAdaptorImpl.java
@@ -1,24 +1,30 @@
 package org.openecomp.core.zusammen.impl;
 
 import com.amdocs.zusammen.adaptor.inbound.api.types.item.Element;
+import com.amdocs.zusammen.adaptor.inbound.api.types.item.ElementConflict;
 import com.amdocs.zusammen.adaptor.inbound.api.types.item.ElementInfo;
+import com.amdocs.zusammen.adaptor.inbound.api.types.item.ItemVersionConflict;
 import com.amdocs.zusammen.adaptor.inbound.api.types.item.ZusammenElement;
 import com.amdocs.zusammen.commons.health.data.HealthInfo;
 import com.amdocs.zusammen.datatypes.Id;
 import com.amdocs.zusammen.datatypes.SessionContext;
-import com.amdocs.zusammen.datatypes.item.*;
+import com.amdocs.zusammen.datatypes.item.Action;
+import com.amdocs.zusammen.datatypes.item.ElementContext;
+import com.amdocs.zusammen.datatypes.item.Info;
+import com.amdocs.zusammen.datatypes.item.Item;
+import com.amdocs.zusammen.datatypes.item.ItemVersion;
+import com.amdocs.zusammen.datatypes.item.ItemVersionData;
+import com.amdocs.zusammen.datatypes.item.ItemVersionStatus;
+import com.amdocs.zusammen.datatypes.item.Resolution;
+import com.amdocs.zusammen.datatypes.itemversion.ItemVersionRevisions;
 import com.amdocs.zusammen.datatypes.itemversion.Tag;
-import com.amdocs.zusammen.datatypes.response.Response;
-import com.amdocs.zusammen.datatypes.response.ReturnCode;
 import org.openecomp.core.zusammen.api.ZusammenAdaptor;
 import org.openecomp.core.zusammen.db.ZusammenConnector;
-import org.openecomp.sdc.datatypes.error.ErrorLevel;
-import org.openecomp.sdc.logging.context.impl.MdcDataErrorMessage;
-import org.openecomp.sdc.logging.types.LoggerConstants;
-import org.openecomp.sdc.logging.types.LoggerErrorCode;
+import org.openecomp.sdc.versioning.dao.types.Revision;
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Comparator;
 import java.util.List;
 import java.util.Optional;
 import java.util.function.Predicate;
@@ -33,30 +39,15 @@
   }
 
   @Override
-  public Optional<ItemVersion> getFirstVersion(SessionContext context, Id itemId) {
-    Collection<ItemVersion> versions = connector.listVersions(context, itemId);
-    if(versions == null || versions.size()==0) {
-      return Optional.empty();
-    }
-    List<ItemVersion> itemVersions = new ArrayList<>(versions);
-    sortItemVersionListByModificationTimeDescOrder(itemVersions);
-    ItemVersion itemVersion = itemVersions.iterator().next();
-
-    return Optional.ofNullable(itemVersion);
-  }
-
-  @Override
   public Optional<ElementInfo> getElementInfo(SessionContext context, ElementContext elementContext,
                                               Id elementId) {
-    Response<ElementInfo> response = connector.getElementInfo(context, elementContext, elementId);
-    return response.isSuccessful() ? Optional.ofNullable(response.getValue()) : Optional.empty();
+    return Optional.ofNullable(connector.getElementInfo(context, elementContext, elementId));
   }
 
   @Override
   public Optional<Element> getElement(SessionContext context, ElementContext elementContext,
                                       String elementId) {
-    Response<Element> response = connector.getElement(context, elementContext, new Id(elementId));
-    return response.isSuccessful() ? Optional.ofNullable(response.getValue()) : Optional.empty();
+    return Optional.ofNullable(connector.getElement(context, elementContext, new Id(elementId)));
   }
 
   @Override
@@ -82,16 +73,14 @@
   public Collection<Element> listElementData(SessionContext context,
                                              ElementContext elementContext,
                                              Id parentElementId) {
-
     Collection<ElementInfo> elementInfoList = connector.listElements(context, elementContext,
         parentElementId);
-    if (elementInfoList != null) {
-      return elementInfoList.stream().map(elementInfo -> connector.getElement(context,
-          elementContext, elementInfo.getId()).getValue()).collect(Collectors.toList());
-    }
 
-    return new ArrayList<>();
-
+    return elementInfoList == null
+        ? new ArrayList<>()
+        : elementInfoList.stream()
+            .map(elementInfo -> connector.getElement(context, elementContext, elementInfo.getId()))
+            .collect(Collectors.toList());
   }
 
 
@@ -119,12 +108,24 @@
   }
 
   @Override
-  public Optional<Element> saveElement(SessionContext context, ElementContext elementContext,
-                                       ZusammenElement element, String message) {
+  public Optional<ElementConflict> getElementConflict(SessionContext context, ElementContext elementContext,
+                                                      Id elementId) {
+    return Optional.ofNullable(connector.getElementConflict(context, elementContext, elementId));
+  }
+
+  @Override
+  public Element saveElement(SessionContext context, ElementContext elementContext,
+                             ZusammenElement element, String message) {
     enrichElementHierarchyRec(context, elementContext, null, element);
     return connector.saveElement(context, elementContext, element, message);
   }
 
+  @Override
+  public void resolveElementConflict(SessionContext context, ElementContext elementContext,
+                                     ZusammenElement element, Resolution resolution) {
+    connector.resolveElementConflict(context, elementContext, element, resolution);
+  }
+
   private void enrichElementHierarchyRec(SessionContext context, ElementContext
       elementContext, Id parentElementId, ZusammenElement element) {
     if (element.getAction() == Action.CREATE) {
@@ -160,20 +161,14 @@
         .findFirst();
   }
 
-  private void logErrorMessageToMdc(ItemElementLoggerTargetServiceName
-                                        itemElementLoggerTargetServiceName,
-                                    ReturnCode returnCode) {
-    logErrorMessageToMdc(itemElementLoggerTargetServiceName, returnCode.toString());
+  @Override
+  public Collection<Item> listItems(SessionContext context) {
+    return connector.listItems(context);
   }
 
-  private void logErrorMessageToMdc(ItemElementLoggerTargetServiceName
-                                        itemElementLoggerTargetServiceName,
-                                    String message) {
-    MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
-        itemElementLoggerTargetServiceName.getDescription(),
-        ErrorLevel.ERROR.name(),
-        LoggerErrorCode.BUSINESS_PROCESS_ERROR.getErrorCode(),
-        message);
+  @Override
+  public Item getItem(SessionContext context, Id itemId) {
+    return connector.getItem(context, itemId);
   }
 
   @Override
@@ -182,15 +177,52 @@
   }
 
   @Override
-  public Id createVersion(SessionContext context, Id itemId, Id baseVersionId, ItemVersionData
-      itemVersionData) {
-    return connector.createVersion(context, itemId, baseVersionId, itemVersionData);
-
+  public void updateItem(SessionContext context, Id itemId, Info info) {
+    connector.updateItem(context, itemId, info);
   }
 
   @Override
-  public Collection<Item> listItems(SessionContext context) {
-    return connector.listItems(context);
+  public Optional<ItemVersion> getFirstVersion(SessionContext context, Id itemId) {
+    Collection<ItemVersion> versions = connector.listPublicVersions(context, itemId);
+    if (versions == null || versions.size() == 0) {
+      return Optional.empty();
+    }
+    List<ItemVersion> itemVersions = new ArrayList<>(versions);
+    sortItemVersionListByModificationTimeDescOrder(itemVersions);
+    ItemVersion itemVersion = itemVersions.iterator().next();
+
+    return Optional.ofNullable(itemVersion);
+  }
+
+  @Override
+  public Collection<ItemVersion> listPublicVersions(SessionContext context, Id itemId) {
+    return connector.listPublicVersions(context, itemId);
+  }
+
+  @Override
+  public ItemVersion getPublicVersion(SessionContext context, Id itemId, Id versionId) {
+    return connector.getPublicVersion(context, itemId, versionId);
+  }
+
+  @Override
+  public ItemVersion getVersion(SessionContext context, Id itemId, Id versionId) {
+    return connector.getVersion(context, itemId, versionId);
+  }
+
+  @Override
+  public ItemVersionStatus getVersionStatus(SessionContext context, Id itemId, Id versionId) {
+    return connector.getVersionStatus(context, itemId, versionId);
+  }
+
+  @Override
+  public ItemVersionConflict getVersionConflict(SessionContext context, Id itemId, Id versionId) {
+    return connector.getVersionConflict(context, itemId, versionId);
+  }
+
+  @Override
+  public Id createVersion(SessionContext context, Id itemId, Id baseVersionId, ItemVersionData
+      itemVersionData) {
+    return connector.createVersion(context, itemId, baseVersionId, itemVersionData);
   }
 
   @Override
@@ -210,25 +242,96 @@
     connector.resetVersionHistory(context, itemId, versionId, changeRef);
   }
 
+  /*@Override
+  public void revertVersionToRevision(SessionContext context, Id itemId, Id versionId,
+                                      Id revisionId) {
+    connector.resetVersionRevision(context, itemId, versionId, revisionId);
+  }*/
+
+  /*@Override
+  public ItemVersionRevisions listVersionRevisions(SessionContext context, Id itemId, Id
+      versionId) {
+    return connector.listVersionRevisions(context, itemId, versionId);
+  }*/
+
   @Override
-  public void updateItem(SessionContext context, Id itemId, Info info) {
-    connector.updateItem(context, itemId, info);
+  public void publishVersion(SessionContext context, Id itemId, Id versionId, String message) {
+    connector.publishVersion(context, itemId, versionId, message);
   }
 
+  @Override
+  public void syncVersion(SessionContext context, Id itemId, Id versionId) {
+    connector.syncVersion(context, itemId, versionId);
+  }
+
+  @Override
+  public void forceSyncVersion(SessionContext context, Id itemId, Id versionId) {
+    connector.forceSyncVersion(context, itemId, versionId);
+  }
 
   @Override
   public Collection<HealthInfo> checkHealth(SessionContext context) {
     return connector.checkHealth(context);
   }
 
-  private static void sortItemVersionListByModificationTimeDescOrder(
-      List<ItemVersion> itemVersions) {
-    itemVersions.sort((o1, o2) -> ((Integer)o2.getId().getValue().length())
-        .compareTo( (o1.getId().getValue().length())));
-  }
-
   @Override
   public String getVersion(SessionContext sessionContext) {
     return connector.getVersion(sessionContext);
   }
+
+  @Override
+  public void revert(SessionContext sessionContext, String itemId, String versionId,
+                     String revisionId) {
+    connector.revertVersionRevision(sessionContext, new Id(itemId), new Id(versionId),
+        new Id(revisionId));
+  }
+
+  @Override
+  public List<Revision> listRevisions(SessionContext sessionContext, String itemId,
+                                      String versionId) {
+    List<Revision> revisions = new ArrayList<>();
+    ItemVersionRevisions itemVersionRevisions =
+        connector.listVersionRevisions(sessionContext, new Id(itemId), new Id
+            (versionId));
+    if(itemVersionRevisions == null || itemVersionRevisions.getItemVersionRevisions()==null ||
+        itemVersionRevisions.getItemVersionRevisions().size()==0) {
+      return revisions;
+    }
+    else{
+      revisions =  itemVersionRevisions.getItemVersionRevisions().stream().map
+          (revision -> {
+        Revision rev = new Revision();
+        rev.setId(revision.getRevisionId().getValue());
+        rev.setTime(revision.getTime());
+        rev.setUser(revision.getUser());
+        rev.setMessage(revision.getMessage());
+        return rev;
+      }).collect(Collectors.toList());
+      revisions.sort(new Comparator<Revision>() {
+        @Override
+        public int compare(Revision o1, Revision o2) {
+          if(o1.getTime().before(o2.getTime())) return 1;
+          else return -1;
+        }
+      });
+      // when creating a new item an initial version is created with
+      // invalid data. this revision is not an applicable revision.
+      //the logic of identifying this revision is:
+      //1- only the first version of item has this issue
+      //2- only in the first item version there are 2 revisions created
+      //3- the second revision is in format "Initial {vlm/vsp}: {name of the vlm/vsp}
+      //4- only if a revision in this format exists we remove the first revision.
+      if(revisions.size()>1 && revisions.get(revisions.size()-2).getMessage().matches("Initial " +
+          ".*:.*")){
+        revisions.remove(revisions.size()-1);
+      }
+      return revisions;
+    }
+  }
+
+  private static void sortItemVersionListByModificationTimeDescOrder(
+      List<ItemVersion> itemVersions) {
+    itemVersions.sort((o1, o2) -> ((Integer) o2.getId().getValue().length())
+        .compareTo((o1.getId().getValue().length())));
+  }
 }
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/pom.xml b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/pom.xml
index fba7d56..f8cfcfd 100644
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/pom.xml
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/pom.xml
@@ -33,5 +33,32 @@
             <artifactId>zusammen-state-store-cassandra-plugin</artifactId>
               <version>${zusammen-state-store.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.testng</groupId>
+            <artifactId>testng</artifactId>
+            <version>${testng.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-all</artifactId>
+            <version>${mockito.all.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.amdocs.zusammen</groupId>
+            <artifactId>zusammen-commons-utils</artifactId>
+            <version>${zusammen.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.openecomp.sdc.core</groupId>
+            <artifactId>openecomp-facade-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.openecomp.sdc.core</groupId>
+            <artifactId>openecomp-session-lib</artifactId>
+            <version>${project.version}</version>
+        </dependency>
     </dependencies>
 </project>
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/ZusammenPluginUtil.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/ZusammenPluginUtil.java
index 59afa70..a973590 100644
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/ZusammenPluginUtil.java
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/ZusammenPluginUtil.java
@@ -19,13 +19,30 @@
 import com.amdocs.zusammen.datatypes.Id;
 import com.amdocs.zusammen.datatypes.SessionContext;
 import com.amdocs.zusammen.datatypes.Space;
-import com.amdocs.zusammen.plugin.statestore.cassandra.dao.types.ElementEntityContext;
+import com.amdocs.zusammen.datatypes.item.Action;
+import com.amdocs.zusammen.datatypes.item.ElementContext;
+import com.amdocs.zusammen.datatypes.item.ItemVersion;
+import com.amdocs.zusammen.datatypes.item.ItemVersionChange;
+import com.amdocs.zusammen.datatypes.item.ItemVersionData;
+import com.amdocs.zusammen.datatypes.item.ItemVersionDataConflict;
 import com.amdocs.zusammen.sdk.collaboration.types.CollaborationElement;
+import com.amdocs.zusammen.sdk.collaboration.types.CollaborationElementChange;
+import com.amdocs.zusammen.sdk.collaboration.types.CollaborationElementConflict;
+import com.amdocs.zusammen.sdk.state.types.StateElement;
+import com.amdocs.zusammen.sdk.types.ElementDescriptor;
 import com.amdocs.zusammen.utils.fileutils.FileUtils;
+import com.amdocs.zusammen.utils.fileutils.json.JsonUtil;
 import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
 
 import java.io.ByteArrayInputStream;
 import java.nio.ByteBuffer;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Base64;
+import java.util.Date;
+
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginConstants.ROOT_ELEMENTS_PARENT_ID;
 
 public class ZusammenPluginUtil {
 
@@ -34,7 +51,7 @@
       case PUBLIC:
         return ZusammenPluginConstants.PUBLIC_SPACE;
       case PRIVATE:
-        return ZusammenPluginUtil.getPrivateSpaceName(context);
+        return getPrivateSpaceName(context);
       default:
         throw new IllegalArgumentException(String.format("Space %s is not supported.", space));
     }
@@ -44,14 +61,54 @@
     return context.getUser().getUserName();
   }
 
-  public static ElementEntity getElementEntity(CollaborationElement element) {
+  public static ElementContext getPrivateElementContext(ElementContext elementContext) {
+    return new ElementContext(elementContext.getItemId(),elementContext.getVersionId(),Id.ZERO);
+  }
+
+
+  public static VersionEntity convertToVersionEntity(Id versionId, Id baseVersionId,
+                                                     Date creationTime,
+                                                     Date modificationTime) {
+
+    return convertToVersionEntity(versionId, null, baseVersionId,
+        creationTime, modificationTime);
+  }
+
+  public static VersionEntity convertToVersionEntity(Id versionId, Id revisionId, Id baseVersionId,
+                                                     Date creationTime,
+                                                     Date modificationTime) {
+    VersionEntity version = new VersionEntity(versionId);
+    version.setBaseId(baseVersionId);
+    version.setCreationTime(creationTime);
+    version.setModificationTime(modificationTime);
+    return version;
+  }
+
+  public static ItemVersion convertToItemVersion(VersionEntity versionEntity,
+                                                 ItemVersionData itemVersionData) {
+    ItemVersion itemVersion = new ItemVersion();
+    itemVersion.setId(versionEntity.getId());
+
+    itemVersion.setBaseId(versionEntity.getBaseId());
+    itemVersion.setCreationTime(versionEntity.getCreationTime());
+    itemVersion.setModificationTime(versionEntity.getModificationTime());
+    itemVersion.setData(itemVersionData);
+    return itemVersion;
+  }
+
+  public static ElementEntity convertToElementEntity(CollaborationElement element) {
+
     ElementEntity elementEntity = new ElementEntity(element.getId());
     elementEntity.setNamespace(element.getNamespace());
     elementEntity.setParentId(element.getParentId() == null
-        ? ZusammenPluginConstants.ROOT_ELEMENTS_PARENT_ID
+        ? ROOT_ELEMENTS_PARENT_ID
         : element.getParentId());
+
+
     elementEntity.setInfo(element.getInfo());
+
     elementEntity.setRelations(element.getRelations());
+
     if (element.getData() != null) {
       elementEntity.setData(ByteBuffer.wrap(FileUtils.toByteArray(element.getData())));
     }
@@ -63,21 +120,29 @@
       elementEntity.setVisualization(
           ByteBuffer.wrap(FileUtils.toByteArray(element.getVisualization())));
     }
+    elementEntity.setElementHash(new Id(calculateElementHash(elementEntity)));
+
     return elementEntity;
   }
 
-  public static CollaborationElement getCollaborationElement(
-      ElementEntityContext elementEntityContext, ElementEntity elementEntity) {
-    Id parentId =
-        ZusammenPluginConstants.ROOT_ELEMENTS_PARENT_ID.equals(elementEntity.getParentId())
-            ? null
-            : elementEntity.getParentId();
-    CollaborationElement element = new CollaborationElement(elementEntityContext.getItemId(),
-        elementEntityContext.getVersionId(), elementEntity.getNamespace(), elementEntity.getId());
+  public static ElementDescriptor convertToElementDescriptor(
+      ElementContext elementContext, ElementEntity elementEntity) {
+    if (elementEntity == null) {
+      return null;
+    }
+    ElementDescriptor element = new ElementDescriptor(elementContext.getItemId(),
+        elementContext.getVersionId(), elementEntity.getNamespace(), elementEntity.getId());
 
-    element.setParentId(parentId);
-    element.setInfo(elementEntity.getInfo());
-    element.setRelations(elementEntity.getRelations());
+    mapElementEntityToDescriptor(elementEntity, element);
+    return element;
+  }
+
+  public static CollaborationElement convertToCollaborationElement(
+      ElementContext elementContext, ElementEntity elementEntity) {
+    CollaborationElement element = new CollaborationElement(elementContext.getItemId(),
+        elementContext.getVersionId(), elementEntity.getNamespace(), elementEntity.getId());
+
+    mapElementEntityToDescriptor(elementEntity, element);
 
     if (elementEntity.getData() != null) {
       element.setData(new ByteArrayInputStream(elementEntity.getData().array()));
@@ -89,7 +154,134 @@
     if (elementEntity.getVisualization() != null) {
       element.setVisualization(new ByteArrayInputStream(elementEntity.getVisualization().array()));
     }
+    return element;
+  }
+
+  public static CollaborationElementChange convertToElementChange(
+      ElementContext changedElementContext, ElementEntity changedElement, Action action) {
+    CollaborationElementChange elementChange = new CollaborationElementChange();
+    elementChange.setElement(convertToCollaborationElement(changedElementContext, changedElement));
+    elementChange.setAction(action);
+    return elementChange;
+  }
+
+  public static ItemVersionChange convertToVersionChange(ElementContext elementContext,
+                                                         ElementEntity versionDataElement,
+                                                         Action action) {
+    ItemVersionChange versionChange = new ItemVersionChange();
+
+    ItemVersion itemVersion = new ItemVersion();
+    itemVersion.setId(elementContext.getVersionId());
+
+    itemVersion.setData(convertToVersionData(versionDataElement));
+
+    versionChange.setItemVersion(itemVersion);
+    versionChange.setAction(action);
+    return versionChange;
+  }
+
+  public static ItemVersionDataConflict getVersionConflict(ElementEntity localVesionData,
+                                                           ElementEntity remoteVersionData) {
+    ItemVersionDataConflict versionConflict = new ItemVersionDataConflict();
+    versionConflict.setLocalData(convertToVersionData(localVesionData));
+    versionConflict.setRemoteData(convertToVersionData(remoteVersionData));
+    return versionConflict;
+  }
+
+  public static CollaborationElementConflict getElementConflict(ElementContext elementContext,
+                                                                ElementEntity localElement,
+                                                                ElementEntity remoteElement) {
+    CollaborationElementConflict elementConflict = new CollaborationElementConflict();
+    elementConflict
+        .setLocalElement(convertToCollaborationElement(elementContext, localElement));
+    elementConflict.setRemoteElement(
+        convertToCollaborationElement(elementContext, remoteElement));
+    return elementConflict;
+  }
+
+  public static ItemVersionData convertToVersionData(ElementEntity versionDataElement) {
+    ItemVersionData versionData = new ItemVersionData();
+    versionData.setInfo(versionDataElement.getInfo());
+    versionData.setRelations(versionDataElement.getRelations());
+    return versionData;
+  }
+
+  private static void mapElementEntityToDescriptor(ElementEntity elementEntity,
+                                                   ElementDescriptor elementDescriptor) {
+    Id parentId = ROOT_ELEMENTS_PARENT_ID.equals(elementEntity.getParentId())
+        ? null
+        : elementEntity.getParentId();
+
+    elementDescriptor.setParentId(parentId);
+    elementDescriptor.setInfo(elementEntity.getInfo());
+    elementDescriptor.setRelations(elementEntity.getRelations());
+    elementDescriptor.setSubElements(elementEntity.getSubElementIds());
+  }
+
+  public static String calculateElementHash(ElementEntity elementEntity) {
+    StringBuffer elementHash = new StringBuffer();
+    if (elementEntity.getData() != null) {
+      elementHash.append(calculateSHA1(elementEntity.getData().array()));
+    } else {
+      elementHash.append("0");
+    }
+    elementHash.append("_");
+    if (elementEntity.getVisualization() != null) {
+      elementHash.append(calculateSHA1(elementEntity.getVisualization().array()));
+    } else {
+      elementHash.append("0");
+    }
+    elementHash.append("_");
+
+    if (elementEntity.getSearchableData() != null) {
+      elementHash.append(calculateSHA1(elementEntity.getSearchableData().array()));
+    } else {
+      elementHash.append("0");
+    }
+    elementHash.append("_");
+
+    if (elementEntity.getInfo() != null) {
+      elementHash.append(calculateSHA1(JsonUtil.object2Json(elementEntity.getInfo()).getBytes()));
+    } else {
+      elementHash.append("0");
+    }
+    elementHash.append("_");
+
+    if (elementEntity.getRelations() != null) {
+      elementHash
+          .append(calculateSHA1(JsonUtil.object2Json(elementEntity.getRelations()).getBytes()));
+    } else {
+      elementHash.append("0");
+    }
+
+    return elementHash.toString();
+  }
+
+  private static String calculateSHA1(byte[] content2Convert) {
+    MessageDigest md = null;
+    try {
+      md = MessageDigest.getInstance("SHA-1");
+    } catch (NoSuchAlgorithmException e) {
+      throw new RuntimeException(e);
+    }
+    return Base64.getEncoder().encodeToString(md.digest(content2Convert));
+  }
+
+
+  public static StateElement getStateElement(ElementContext elementContext, ElementEntity
+      elementEntity) {
+    Id parentId = ROOT_ELEMENTS_PARENT_ID.equals(elementEntity.getParentId())
+        ? null
+        : elementEntity.getParentId();
+    StateElement element = new StateElement(elementContext.getItemId(),
+        elementContext.getVersionId(), elementEntity.getNamespace(), elementEntity.getId());
+
+    element.setParentId(parentId);
+    element.setInfo(elementEntity.getInfo());
+    element.setRelations(elementEntity.getRelations());
     element.setSubElements(elementEntity.getSubElementIds());
     return element;
   }
+
+
 }
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/CommitStagingService.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/CommitStagingService.java
new file mode 100644
index 0000000..45d5769
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/CommitStagingService.java
@@ -0,0 +1,100 @@
+package org.openecomp.core.zusammen.plugin.collaboration;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.item.ElementContext;
+import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.StageEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
+
+import java.util.Collection;
+import java.util.Optional;
+
+public class CommitStagingService {
+
+  private VersionPrivateStore versionPrivateStore;
+  private VersionStageStore versionStageStore;
+  private ElementPrivateStore elementPrivateStore;
+  private ElementStageStore elementStageStore;
+
+  public CommitStagingService(VersionPrivateStore versionPrivateStore,
+                              VersionStageStore versionStageStore,
+                              ElementPrivateStore elementPrivateStore,
+                              ElementStageStore elementStageStore) {
+    this.versionPrivateStore = versionPrivateStore;
+    this.versionStageStore = versionStageStore;
+    this.elementPrivateStore = elementPrivateStore;
+    this.elementStageStore = elementStageStore;
+  }
+
+  public void commitStaging(SessionContext context, Id itemId, Id versionId) {
+    Optional<StageEntity<VersionEntity>> versionStage =
+        versionStageStore.get(context, itemId, new VersionEntity(versionId));
+
+    final ElementContext elementContext = new ElementContext(itemId, versionId, Id.ZERO);
+    Collection<ElementEntity> stagedElementIds = elementStageStore.listIds(context, elementContext);
+
+    if ((!versionStage.isPresent() && stagedElementIds.isEmpty()) ||
+        elementStageStore.hasConflicts(context, elementContext)) {
+      return;
+    }
+
+    versionStage.ifPresent(verStage -> commitVersionStage(context, itemId, verStage));
+    commitElementsStage(context, elementContext, stagedElementIds);
+  }
+
+  private void commitVersionStage(SessionContext context, Id itemId,
+                                  StageEntity<VersionEntity> versionStage) {
+    switch (versionStage.getAction()) {
+      case CREATE:
+        versionPrivateStore.commitStagedCreate(context, itemId, versionStage.getEntity(),
+            versionStage.getPublishTime());
+        break;
+      case UPDATE:
+        versionPrivateStore.commitStagedUpdate(context, itemId, versionStage.getEntity(),
+            versionStage.getPublishTime());
+        break;
+      case IGNORE:
+        versionPrivateStore.commitStagedIgnore(context, itemId, versionStage.getEntity(),
+            versionStage.getPublishTime());
+        break;
+      default:
+        throw new UnsupportedOperationException(
+            "Version change other then Create/Update/Ignore is not supported");
+    }
+
+    versionStageStore.delete(context, itemId, versionStage.getEntity());
+  }
+
+  private void commitElementsStage(SessionContext context, ElementContext elementContext,
+                                   Collection<ElementEntity> stagedElementIds) {
+    for (ElementEntity stagedElementId : stagedElementIds) {
+      StageEntity<ElementEntity> stagedElement =
+          elementStageStore.get(context, elementContext, stagedElementId)
+              .orElseThrow(
+                  () -> new IllegalStateException("Element id returned by list must exist"));
+      switch (stagedElement.getAction()) {
+        case CREATE:
+          elementPrivateStore.commitStagedCreate(context, elementContext, stagedElement.getEntity(),
+              stagedElement.getPublishTime());
+          break;
+        case UPDATE:
+          elementPrivateStore.commitStagedUpdate(context, elementContext, stagedElement.getEntity(),
+              stagedElement.getPublishTime());
+          break;
+        case DELETE:
+          elementPrivateStore
+              .commitStagedDelete(context, elementContext, stagedElement.getEntity());
+          break;
+        case IGNORE:
+          elementPrivateStore.commitStagedIgnore(context, elementContext, stagedElement.getEntity(),
+              stagedElement.getPublishTime());
+          break;
+        default:
+          throw new UnsupportedOperationException(
+              "Element change other then Create/Update/Delete/Ignore is not supported");
+      }
+      elementStageStore.delete(context, elementContext, stagedElement.getEntity());
+    }
+  }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ElementCollaborationStore.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ElementCollaborationStore.java
deleted file mode 100644
index ac103c0..0000000
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ElementCollaborationStore.java
+++ /dev/null
@@ -1,119 +0,0 @@
-package org.openecomp.core.zusammen.plugin.collaboration;
-
-import com.amdocs.zusammen.datatypes.Id;
-import com.amdocs.zusammen.datatypes.SessionContext;
-import com.amdocs.zusammen.datatypes.item.ElementContext;
-import com.amdocs.zusammen.plugin.statestore.cassandra.dao.types.ElementEntityContext;
-import com.amdocs.zusammen.sdk.collaboration.types.CollaborationElement;
-import org.openecomp.core.zusammen.plugin.ZusammenPluginConstants;
-import org.openecomp.core.zusammen.plugin.ZusammenPluginUtil;
-import org.openecomp.core.zusammen.plugin.dao.ElementRepository;
-import org.openecomp.core.zusammen.plugin.dao.ElementRepositoryFactory;
-import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Optional;
-
-import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.getCollaborationElement;
-import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.getSpaceName;
-
-
-public class ElementCollaborationStore {
-
-  private static final String SUB_ELEMENT_NOT_EXIST_ERROR_MSG =
-      "List sub elements error: item %s, version %s - " +
-          "element %s, which appears as sub element of element %s, does not exist";
-
-  public Collection<CollaborationElement> listElements(SessionContext context,
-                                                       ElementContext elementContext,
-                                                       Id elementId) {
-    ElementEntityContext elementEntityContext =
-        new ElementEntityContext(ZusammenPluginUtil.getPrivateSpaceName(context), elementContext);
-
-    if (elementId == null) {
-      elementId = ZusammenPluginConstants.ROOT_ELEMENTS_PARENT_ID;
-    }
-
-    ElementRepository elementRepository = getElementRepository(context);
-    String elementIdValue = elementId.getValue();
-    String versionIdValue = elementContext.getChangeRef() == null
-        ? elementContext.getVersionId().getValue()
-        : elementContext.getChangeRef();
-    Collection<CollaborationElement> subElements = new ArrayList<>();
-
-    Optional<ElementEntity> element =
-        elementRepository.get(context, elementEntityContext, new ElementEntity(elementId));
-    if (element.isPresent() && element.get().getSubElementIds() != null) {
-      for (Id subElementId : element.get().getSubElementIds()) {
-        ElementEntity subElement =
-            elementRepository.get(context, elementEntityContext, new ElementEntity(subElementId))
-                .orElseThrow(
-                    () -> new IllegalStateException(String.format(SUB_ELEMENT_NOT_EXIST_ERROR_MSG,
-                        elementContext.getItemId().getValue(), versionIdValue,
-                        subElementId.getValue(), elementIdValue)));
-        subElements.add(getCollaborationElement(elementEntityContext, subElement));
-      }
-    }
-    return subElements;
-  }
-
-  public CollaborationElement getElement(SessionContext context, ElementContext elementContext,
-                                         Id elementId) {
-    ElementEntityContext elementEntityContext =
-        new ElementEntityContext(ZusammenPluginUtil.getPrivateSpaceName(context), elementContext);
-    return getElementRepository(context)
-        .get(context, elementEntityContext, new ElementEntity(elementId))
-        .map(elementEntity -> getCollaborationElement(elementEntityContext, elementEntity))
-        .orElse(null);
-  }
-
-  public void createElement(SessionContext context, CollaborationElement element) {
-    getElementRepository(context)
-        .create(context,
-            new ElementEntityContext(getSpaceName(context, element.getSpace()),
-                element.getItemId(), element.getVersionId()),
-            ZusammenPluginUtil.getElementEntity(element));
-  }
-
-  public void updateElement(SessionContext context, CollaborationElement element) {
-    getElementRepository(context)
-        .update(context,
-            new ElementEntityContext(getSpaceName(context, element.getSpace()),
-                element.getItemId(), element.getVersionId()),
-            ZusammenPluginUtil.getElementEntity(element));
-  }
-
-  public void deleteElement(SessionContext context, CollaborationElement element) {
-    deleteElementHierarchy(getElementRepository(context),
-        context,
-        new ElementEntityContext(getSpaceName(context, element.getSpace()),
-            element.getItemId(), element.getVersionId()),
-        ZusammenPluginUtil.getElementEntity(element));
-  }
-
-  public boolean checkHealth(SessionContext sessionContext) {
-    return getElementRepository(sessionContext).checkHealth(sessionContext);
-  }
-
-  private void deleteElementHierarchy(ElementRepository elementRepository, SessionContext context,
-                                      ElementEntityContext elementEntityContext,
-                                      ElementEntity elementEntity) {
-    Optional<ElementEntity> retrieved =
-        elementRepository.get(context, elementEntityContext, elementEntity);
-    if (!retrieved.isPresent()) {
-      return;
-    }
-    retrieved.get().getSubElementIds().stream()
-        .map(ElementEntity::new)
-        .forEach(subElementEntity -> deleteElementHierarchy(
-            elementRepository, context, elementEntityContext, subElementEntity));
-
-    // only for the first one the parentId will populated (so it'll be removed from its parent)
-    elementRepository.delete(context, elementEntityContext, elementEntity);
-  }
-
-  protected ElementRepository getElementRepository(SessionContext context) {
-    return ElementRepositoryFactory.getInstance().createInterface(context);
-  }
-}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ElementPrivateStore.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ElementPrivateStore.java
new file mode 100644
index 0000000..045def2
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ElementPrivateStore.java
@@ -0,0 +1,48 @@
+package org.openecomp.core.zusammen.plugin.collaboration;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.item.ElementContext;
+import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.SynchronizationStateEntity;
+
+import java.util.Collection;
+import java.util.Date;
+import java.util.Map;
+import java.util.Optional;
+
+public interface ElementPrivateStore extends ElementStore {
+
+  Map<Id, Id> listIds(SessionContext context, ElementContext elementContext);
+
+  Collection<ElementEntity> listSubs(SessionContext context, ElementContext elementContext,
+                                     Id elementId);
+
+  Optional<SynchronizationStateEntity> getSynchronizationState(SessionContext context,
+                                                               ElementContext elementContext,
+                                                               Id elementId);
+
+  void create(SessionContext context, ElementContext elementContext, ElementEntity element);
+
+  boolean update(SessionContext context, ElementContext elementContext, ElementEntity element);
+
+  void delete(SessionContext context, ElementContext elementContext, ElementEntity element);
+
+  void markAsPublished(SessionContext context, ElementContext elementContext, Id elementId,
+                       Date publishTime);
+
+  void markDeletionAsPublished(SessionContext context, ElementContext elementContext, Id elementId,
+                               Date publishTime);
+
+  void commitStagedCreate(SessionContext context, ElementContext elementContext,
+                          ElementEntity element, Date publishTime);
+
+  void commitStagedUpdate(SessionContext context, ElementContext elementContext,
+                          ElementEntity element, Date publishTime);
+
+  void commitStagedDelete(SessionContext context, ElementContext elementContext,
+                          ElementEntity element);
+
+  void commitStagedIgnore(SessionContext context, ElementContext elementContext,
+                          ElementEntity element, Date publishTime);
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ElementPublicStore.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ElementPublicStore.java
new file mode 100644
index 0000000..0f1790a
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ElementPublicStore.java
@@ -0,0 +1,23 @@
+package org.openecomp.core.zusammen.plugin.collaboration;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.item.ElementContext;
+import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
+
+import java.util.Date;
+import java.util.Map;
+
+public interface ElementPublicStore extends ElementStore {
+
+  void create(SessionContext context, ElementContext elementContext, ElementEntity element,
+              Date publishTime);
+
+  void update(SessionContext context, ElementContext elementContext, ElementEntity element,
+              Date publishTime);
+
+  void delete(SessionContext context, ElementContext elementContext, ElementEntity element,
+              Date publishTime);
+
+  Map<Id,Id> listIds(SessionContext context, ElementContext elementContext);
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ElementStageStore.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ElementStageStore.java
new file mode 100644
index 0000000..a923624
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ElementStageStore.java
@@ -0,0 +1,35 @@
+package org.openecomp.core.zusammen.plugin.collaboration;
+
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.item.ElementContext;
+import com.amdocs.zusammen.datatypes.item.Resolution;
+import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.StageEntity;
+
+import java.util.Collection;
+import java.util.Optional;
+
+public interface ElementStageStore {
+
+  Collection<ElementEntity> listIds(SessionContext context, ElementContext elementContext);
+
+  boolean hasConflicts(SessionContext context, ElementContext elementContext);
+
+  Collection<StageEntity<ElementEntity>> listConflictedDescriptors(SessionContext context,
+                                                                   ElementContext elementContext);
+
+  Optional<StageEntity<ElementEntity>> get(SessionContext context, ElementContext elementContext,
+                                           ElementEntity element);
+
+  Optional<StageEntity<ElementEntity>> getConflicted(SessionContext context,
+                                                     ElementContext elementContext,
+                                                     ElementEntity element);
+
+  void create(SessionContext context, ElementContext elementContext,
+              StageEntity<ElementEntity> elementStage);
+
+  void delete(SessionContext context, ElementContext elementContext, ElementEntity element);
+
+  void resolveConflict(SessionContext context, ElementContext elementContext, ElementEntity element,
+                       Resolution resolution);
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ElementStore.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ElementStore.java
new file mode 100644
index 0000000..1c26a81
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ElementStore.java
@@ -0,0 +1,20 @@
+package org.openecomp.core.zusammen.plugin.collaboration;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.item.ElementContext;
+import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.SynchronizationStateEntity;
+
+import java.util.Collection;
+import java.util.Optional;
+
+public interface ElementStore {
+  Optional<ElementEntity> get(SessionContext context, ElementContext elementContext, Id elementId);
+
+  Optional<ElementEntity> getDescriptor(SessionContext context, ElementContext elementContext,
+                                        Id elementId);
+
+  Collection<SynchronizationStateEntity> listSynchronizationStates(SessionContext context,
+                                                                   ElementContext elementContext);
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ErrorCode.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ErrorCode.java
new file mode 100644
index 0000000..3d09100
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/ErrorCode.java
@@ -0,0 +1,5 @@
+package org.openecomp.core.zusammen.plugin.collaboration;
+
+public class ErrorCode {
+  public static final int NO_CHANGES_TO_PUBLISH = 60000;
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/Message.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/Message.java
new file mode 100644
index 0000000..2816974
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/Message.java
@@ -0,0 +1,6 @@
+package org.openecomp.core.zusammen.plugin.collaboration;
+
+public class Message {
+  public static final String NO_CHANGES_TO_PUBLISH =
+      "Item Id %s, version Id %s: There are no changes to publish.";
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/PublishService.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/PublishService.java
new file mode 100644
index 0000000..7b043c8
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/PublishService.java
@@ -0,0 +1,201 @@
+package org.openecomp.core.zusammen.plugin.collaboration;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.item.Action;
+import com.amdocs.zusammen.datatypes.item.ElementContext;
+import com.amdocs.zusammen.datatypes.response.ReturnCode;
+import com.amdocs.zusammen.datatypes.response.ZusammenException;
+import com.amdocs.zusammen.sdk.collaboration.types.CollaborationMergeChange;
+import com.amdocs.zusammen.sdk.collaboration.types.CollaborationPublishResult;
+import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.SynchronizationStateEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
+
+import java.util.Collection;
+import java.util.Date;
+import java.util.Map;
+import java.util.Optional;
+import java.util.UUID;
+
+import static com.amdocs.zusammen.datatypes.response.Module.ZCSP;
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginConstants.ROOT_ELEMENTS_PARENT_ID;
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.convertToElementChange;
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.convertToVersionChange;
+import static org.openecomp.core.zusammen.plugin.collaboration.ErrorCode.NO_CHANGES_TO_PUBLISH;
+
+public class PublishService {
+  // TODO: 6/29/2017 throw ZusammenException with ReturnCode when needed.
+  private static final String PUSH_NON_EXISTING_VERSION =
+      "Item Id %s, version Id %s: Non existing version cannot be pushed.";
+
+  private VersionPublicStore versionPublicStore;
+  private VersionPrivateStore versionPrivateStore;
+  private ElementPublicStore elementPublicStore;
+  private ElementPrivateStore elementPrivateStore;
+
+  public PublishService(VersionPublicStore versionPublicStore,
+                        VersionPrivateStore versionPrivateStore,
+                        ElementPublicStore elementPublicStore,
+                        ElementPrivateStore elementPrivateStore) {
+    this.versionPublicStore = versionPublicStore;
+    this.versionPrivateStore = versionPrivateStore;
+    this.elementPublicStore = elementPublicStore;
+    this.elementPrivateStore = elementPrivateStore;
+  }
+
+  public CollaborationPublishResult publish(SessionContext context, Id itemId, Id versionId,
+                                            String message) {
+    CollaborationPublishResult result = new CollaborationPublishResult();
+    result.setChange(new CollaborationMergeChange());
+
+    Date publishTime = new Date();
+    Id revisionId = new Id(UUID.randomUUID().toString());
+    boolean versionFirstPublication = publishVersion(context, itemId, versionId, revisionId,
+        publishTime,message);
+    if (versionFirstPublication) {
+      publishAllElements(context, new ElementContext(itemId, versionId, revisionId), publishTime,
+          result);
+    } else {
+      publishDirtyElements(context, new ElementContext(itemId, versionId, revisionId), publishTime,
+          result);
+    }
+    return result;
+  }
+
+  private boolean publishVersion(SessionContext context, Id itemId, Id versionId, Id revisionId,
+                                 Date publishTime, String message) {
+    SynchronizationStateEntity privateVersionSyncState =
+        versionPrivateStore.getSynchronizationState(context, itemId, versionId)
+            .orElseThrow(() -> new IllegalArgumentException(
+                String.format(PUSH_NON_EXISTING_VERSION, itemId.toString(), versionId.toString())));
+
+    if (!privateVersionSyncState.isDirty()) {
+      throw new ZusammenException(new ReturnCode(NO_CHANGES_TO_PUBLISH, ZCSP,
+          String.format(Message.NO_CHANGES_TO_PUBLISH, itemId, versionId), null));
+    }
+
+    Optional<SynchronizationStateEntity> publicVersionSyncState =
+        versionPublicStore.getSynchronizationState(context, itemId, versionId);
+
+    // private must be synced with public (if public exists)
+    if (publicVersionSyncState.isPresent() &&
+        !privateVersionSyncState.getPublishTime()
+            .equals(publicVersionSyncState.get().getPublishTime())) {
+      // should not happen as it is validated in zusammen-core
+      throw new UnsupportedOperationException("Out of sync item version can not be publish");
+    }
+
+    boolean versionFirstPublication;
+    Map<Id, Id> versionElementIds =
+        elementPublicStore.listIds(context, new ElementContext(itemId,
+            versionId));
+    if (publicVersionSyncState.isPresent()) {
+      versionPublicStore.update(context, itemId, new VersionEntity(versionId), revisionId,
+          versionElementIds,publishTime,message);
+      versionFirstPublication = false;
+    } else {
+      VersionEntity privateVersion = versionPrivateStore.get(context, itemId, versionId)
+          .orElseThrow(() -> new IllegalArgumentException(
+              String.format(PUSH_NON_EXISTING_VERSION, itemId.toString(), versionId.toString())));
+      versionPublicStore.create(context, itemId, privateVersion, revisionId,versionElementIds,
+          publishTime,message);
+      versionFirstPublication = true;
+    }
+    versionPrivateStore.markAsPublished(context, itemId, versionId, publishTime);
+    return versionFirstPublication;
+  }
+
+  private void publishAllElements(SessionContext context, ElementContext elementContext,
+                                  Date publishTime, CollaborationPublishResult result) {
+    Collection<SynchronizationStateEntity> privateElementSyncStates =
+        elementPrivateStore.listSynchronizationStates(context, elementContext);
+
+    for (SynchronizationStateEntity privateElementSyncState : privateElementSyncStates) {
+      Optional<ElementEntity> privateElement =
+          elementPrivateStore.get(context, elementContext, privateElementSyncState.getId());
+
+      if (!privateElement.isPresent()) {
+        continue;
+      }
+      ElementEntity elementToPublish = privateElement.get();
+
+      elementPublicStore.create(context, elementContext, elementToPublish,
+          privateElementSyncState.isDirty() ? publishTime
+              : privateElementSyncState.getPublishTime());
+
+      if (privateElementSyncState.isDirty()) {
+        elementPrivateStore
+            .markAsPublished(context, elementContext, privateElementSyncState.getId(), publishTime);
+      }
+      updateResult(elementContext, elementToPublish, Action.CREATE,
+          ROOT_ELEMENTS_PARENT_ID.equals(privateElementSyncState.getId()), result);
+    }
+  }
+
+  private void publishDirtyElements(SessionContext context, ElementContext elementContext,
+                                    Date publishTime, CollaborationPublishResult result) {
+
+    Id revisionId = elementContext.getRevisionId();
+    elementContext.setRevisionId(revisionId);
+    ElementContext privateElementContext = new ElementContext(elementContext.getItemId(),
+        elementContext.getVersionId(),Id.ZERO);
+    Collection<SynchronizationStateEntity> privateElementSyncStates =
+        elementPrivateStore.listSynchronizationStates(context, elementContext);
+
+    Collection<SynchronizationStateEntity> publicElementSyncStates =
+        elementPublicStore.listSynchronizationStates(context, elementContext);
+
+    for (SynchronizationStateEntity privateElementSyncState : privateElementSyncStates) {
+      if (!privateElementSyncState.isDirty()) {
+        continue;
+      }
+
+      Optional<ElementEntity> privateElement =
+          elementPrivateStore.get(context, privateElementContext, privateElementSyncState.getId());
+
+      ElementEntity elementToPublish;
+      Action actionOnPublic;
+      if (privateElement.isPresent()) {
+        elementToPublish = privateElement.get();
+
+        if (publicElementSyncStates.contains(privateElementSyncState)) {
+
+          elementPublicStore.update(context, elementContext, elementToPublish, publishTime);
+          actionOnPublic = Action.UPDATE;
+        } else {
+          elementPublicStore.create(context, elementContext, elementToPublish, publishTime);
+          actionOnPublic = Action.CREATE;
+        }
+
+        elementPrivateStore
+            .markAsPublished(context, privateElementContext, privateElementSyncState.getId(), publishTime);
+      } else {
+        elementToPublish =
+            elementPublicStore.get(context, elementContext, privateElementSyncState.getId())
+                .orElseThrow(() -> new IllegalStateException(
+                    "Element that should be deleted from public must exist there"));
+        elementPublicStore.delete(context, elementContext, elementToPublish, publishTime);
+        actionOnPublic = Action.DELETE;
+
+        elementPrivateStore
+            .markDeletionAsPublished(context, privateElementContext, privateElementSyncState.getId(),
+                publishTime);
+      }
+
+      updateResult(elementContext, elementToPublish, actionOnPublic,
+          ROOT_ELEMENTS_PARENT_ID.equals(privateElementSyncState.getId()), result);
+    }
+  }
+
+  private void updateResult(ElementContext elementContext, ElementEntity element,
+                            Action action, boolean versionDataElement,
+                            CollaborationPublishResult result) {
+    if (versionDataElement) {
+      result.getChange().setChangedVersion(convertToVersionChange(elementContext, element, action));
+    } else {
+      result.getChange().getChangedElements()
+          .add(convertToElementChange(elementContext, element, action));
+    }
+  }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/RevertService.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/RevertService.java
new file mode 100644
index 0000000..0d2ea2c
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/RevertService.java
@@ -0,0 +1,161 @@
+package org.openecomp.core.zusammen.plugin.collaboration;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.item.ElementContext;
+import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.SynchronizationStateEntity;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+
+public class RevertService {
+
+  private ElementPublicStore elementPublicStore;
+  private ElementPrivateStore elementPrivateStore;
+
+  public RevertService(ElementPublicStore elementPublicStore,
+                       ElementPrivateStore elementPrivateStore) {
+    this.elementPublicStore = elementPublicStore;
+    this.elementPrivateStore = elementPrivateStore;
+  }
+
+  public void revert(SessionContext context, Id itemId, Id versionId, Id revisionId) {
+    ElementContext targetContext = new ElementContext(itemId, versionId);
+    ElementContext sourceContext = new ElementContext(itemId, versionId, revisionId);
+    copyElementsFromPublic(context, sourceContext, targetContext);
+  }
+
+  private void copyElementsFromPublic(SessionContext context, ElementContext sourceContext,
+                                      ElementContext targetContext) {
+    Collection<RevertElementAction> revertElementActions =
+        evaluateRevertElementActions(context, sourceContext, targetContext);
+
+    revertElementActions.forEach(revertElementAction -> revertElementAction.run(context));
+  }
+
+  private Collection<RevertElementAction> evaluateRevertElementActions(SessionContext context,
+                                                                       ElementContext sourceContext,
+                                                                       ElementContext targetContext) {
+
+    Map<Id, Id> sourceElements = elementPublicStore.listIds(context, sourceContext);
+    Map<Id, Id> targetPublicElements = elementPublicStore.listIds(context, targetContext);
+    Collection<SynchronizationStateEntity> synchronizationStateEntities =
+        elementPrivateStore.listSynchronizationStates(context, targetContext);
+
+    Map<Id, Id> targetElements =
+        evaluateTargetElements(targetPublicElements, synchronizationStateEntities);
+
+
+    Collection<RevertElementAction> revertElementActions = new ArrayList<>();
+
+    sourceElements.entrySet().forEach(entry -> {
+      Id sourceElementId = entry.getKey();
+      Id sourceElementRevisionId = entry.getValue();
+
+      if (!targetElements.containsKey(sourceElementId)) {
+        revertElementActions
+            .add(new RevertElementAction(sourceContext, sourceElementId, commands[CREATE]));
+      } else if (!targetElements.get(sourceElementId).equals(sourceElementRevisionId)) {
+        revertElementActions
+            .add(new RevertElementAction(sourceContext, sourceElementId, commands[UPDATE]));
+      }
+    });
+
+    targetElements.entrySet().forEach(entry -> {
+      Id targetElementId = entry.getKey();
+      if (!sourceElements.containsKey(targetElementId)) {
+        revertElementActions
+            .add(new RevertElementAction(targetContext, targetElementId, commands[DELETE]));
+      }
+    });
+
+    return revertElementActions;
+  }
+
+  private Map<Id, Id> evaluateTargetElements(Map<Id, Id> targetPublicElements,
+                                             Collection<SynchronizationStateEntity> syncStates) {
+    Map<Id, Id> targetElements = new HashMap<>(targetPublicElements);
+    syncStates.stream()
+        .filter(SynchronizationStateEntity::isDirty)
+        .forEach(syncState -> targetElements.put(syncState.getId(), Id.ZERO));
+    return targetElements;
+  }
+
+  private static class RevertElementAction {
+    private ElementContext elementContext;
+    private Id elementId;
+    private ActionCommand command;
+
+    private RevertElementAction(ElementContext elementContext, Id elementId,
+                                ActionCommand command) {
+      this.elementContext = elementContext;
+      this.elementId = elementId;
+      this.command = command;
+    }
+
+    public ElementContext getElementContext() {
+      return elementContext;
+    }
+
+    public Id getElementId() {
+      return elementId;
+    }
+
+    public void run(SessionContext context) {
+      command.run(context, elementContext, elementId);
+    }
+  }
+
+  private interface ActionCommand {
+    void run(SessionContext context, ElementContext elementContext, Id elementId);
+  }
+
+  private static int CREATE = 0;
+  private static int UPDATE = 1;
+  private static int DELETE = 2;
+
+  private ActionCommand[] commands = {new ActionCommand() {
+    @Override
+    public void run(SessionContext context, ElementContext elementContext, Id elementId) {
+      //create
+      Optional<ElementEntity> element = elementPublicStore.get(context, elementContext, elementId);
+      if (!element.isPresent()) {
+        throw getMissingElementException(elementContext, elementId);
+      }
+      elementPrivateStore.create(context, elementContext, element.get());
+    }
+  }, new ActionCommand() {
+    @Override
+    public void run(SessionContext context, ElementContext elementContext, Id elementId) {
+      //update
+      Optional<ElementEntity> element = elementPublicStore.get(context, elementContext, elementId);
+      if (!element.isPresent()) {
+        throw getMissingElementException(elementContext, elementId);
+      }
+      elementPrivateStore.update(context, elementContext, element.get());
+    }
+  }, new ActionCommand() {
+    @Override
+    public void run(SessionContext context, ElementContext elementContext, Id elementId) {
+      //delete
+      Optional<ElementEntity> element = elementPrivateStore.get(context, elementContext, elementId);
+      if (!element.isPresent()) {
+        return; // deleted by parent when hierarchy was deleted
+      }
+      elementPrivateStore.delete(context, elementContext, element.get());
+    }
+  }};
+
+  private RuntimeException getMissingElementException(ElementContext elementContext,
+                                                      Id elementId) {
+    return new IllegalStateException(
+        String.format("Item Id %s, version Id %s, revision Id %s: Missing element with Id %s",
+            elementContext.getItemId().getValue(), elementContext.getVersionId().getValue(),
+            elementContext.getRevisionId().getValue(), elementId.getValue())
+    );
+  }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/SyncService.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/SyncService.java
new file mode 100644
index 0000000..04a7e9f
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/SyncService.java
@@ -0,0 +1,384 @@
+package org.openecomp.core.zusammen.plugin.collaboration;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.item.Action;
+import com.amdocs.zusammen.datatypes.item.ElementContext;
+import com.amdocs.zusammen.sdk.collaboration.types.CollaborationMergeChange;
+import com.amdocs.zusammen.sdk.collaboration.types.CollaborationMergeConflict;
+import com.amdocs.zusammen.sdk.collaboration.types.CollaborationMergeResult;
+import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.StageEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.SynchronizationStateEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
+
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginConstants.ROOT_ELEMENTS_PARENT_ID;
+
+public class SyncService {
+  private static final String PULL_NON_EXISTING_VERSION =
+      "Item Id %s, version Id %s: Non existing version cannot be synced.";
+  private static final String PUBLIC_SYNC_STATE_EXISTS_WITHOUT_ELEMENT =
+      "Item Id %s, version Id %s: Sync state of element with Id %s " +
+          "exists in public space while the element does not";
+  private static final String PRIVATE_UNPUBLISHED_SYNC_STATE_EXISTS_WITHOUT_ELEMENT =
+      "Item Id %s, version Id %s: Sync state of unpublished element with Id %s " +
+          "exists in private space while the element does not";
+
+  private VersionPublicStore versionPublicStore;
+  private VersionPrivateStore versionPrivateStore;
+  private VersionStageStore versionStageStore;
+  private ElementPublicStore elementPublicStore;
+  private ElementPrivateStore elementPrivateStore;
+  private ElementStageStore elementStageStore;
+
+  public SyncService(VersionPublicStore versionPublicStore,
+                     VersionPrivateStore versionPrivateStore,
+                     VersionStageStore versionStageStore,
+                     ElementPublicStore elementPublicStore,
+                     ElementPrivateStore elementPrivateStore,
+                     ElementStageStore elementStageStore) {
+    this.versionPublicStore = versionPublicStore;
+    this.versionPrivateStore = versionPrivateStore;
+    this.versionStageStore = versionStageStore;
+    this.elementPublicStore = elementPublicStore;
+    this.elementPrivateStore = elementPrivateStore;
+    this.elementStageStore = elementStageStore;
+  }
+
+  public CollaborationMergeResult sync(SessionContext context, Id itemId, Id versionId,
+                                       boolean force) {
+    SynchronizationStateEntity publicVersionSyncState =
+        versionPublicStore.getSynchronizationState(context, itemId, versionId)
+            .orElseThrow(() -> new IllegalStateException(
+                String.format(PULL_NON_EXISTING_VERSION, itemId.toString(), versionId.toString())));
+
+    Date publishTime = publicVersionSyncState.getPublishTime();
+
+    Optional<SynchronizationStateEntity> privateVersionSyncState =
+        versionPrivateStore.getSynchronizationState(context, itemId, versionId);
+
+    if (force || !privateVersionSyncState.isPresent() ||
+        !publishTime.equals(privateVersionSyncState.get().getPublishTime())) {
+      ElementContext elementContext =
+          new ElementContext(itemId, versionId, publicVersionSyncState.getRevisionId());
+
+      Collection<SynchronizationStateEntity> publicSyncStates =
+          elementPublicStore.listSynchronizationStates(context, elementContext);
+      Collection<SynchronizationStateEntity> privateSyncStates =
+          elementPrivateStore.listSynchronizationStates(context, elementContext);
+      Map<Id, SynchronizationStateEntity> publicSyncStateById = toMapById(publicSyncStates);
+
+      Set<Id> syncedElements = new HashSet<>();
+      if (force) {
+        List<SynchronizationStateEntity> dirtyPrivateSyncStates = privateSyncStates.stream()
+            .filter(SynchronizationStateEntity::isDirty)
+            .collect(Collectors.toList());
+
+        forceSyncDirtyElements(context, elementContext, dirtyPrivateSyncStates, publicSyncStateById,
+            syncedElements);
+      }
+
+      if (!privateVersionSyncState.isPresent() ||
+          !publishTime.equals(privateVersionSyncState.get().getPublishTime())) {
+        syncVersion(context, itemId, versionId, publishTime, privateVersionSyncState.isPresent());
+        syncElements(context, elementContext,
+            privateVersionSyncState.map(SynchronizationStateEntity::getPublishTime).orElse(null),
+            publicSyncStates, privateSyncStates, publicSyncStateById, syncedElements);
+      }
+    }
+
+    return createResult();
+  }
+
+  private CollaborationMergeResult createResult() {
+    CollaborationMergeResult result = new CollaborationMergeResult();
+    result.setChange(new CollaborationMergeChange());
+    result.setConflict(new CollaborationMergeConflict());
+    return result;
+  }
+
+  private void syncVersion(SessionContext context, Id itemId, Id versionId, Date publishTime,
+                           boolean versionExistOnPrivate) {
+    if (versionExistOnPrivate) {
+      stageVersion(context, itemId, new VersionEntity(versionId), Action.UPDATE, publishTime);
+    } else {
+      stageVersion(context, itemId, versionPublicStore.get(context, itemId, versionId)
+              .orElseThrow(() -> new IllegalArgumentException(String
+                  .format(PULL_NON_EXISTING_VERSION, itemId.toString(), versionId.toString()))),
+          Action.CREATE, publishTime);
+    }
+  }
+
+  private void syncElements(SessionContext context, ElementContext elementContext,
+                            Date previousSyncedPublishTime,
+                            Collection<SynchronizationStateEntity> publicSyncStates,
+                            Collection<SynchronizationStateEntity> privateSyncStates,
+                            Map<Id, SynchronizationStateEntity> publicSyncStateById,
+                            Set<Id> syncedElements) {
+    Map<Id, SynchronizationStateEntity> privateSyncStateById = toMapById(privateSyncStates);
+
+    Collection<SynchronizationStateEntity> updatedPublicSyncStates =
+        previousSyncedPublishTime == null
+            ? publicSyncStates
+            : publicSyncStates.stream()
+                .filter(syncState -> syncState.getPublishTime().after(previousSyncedPublishTime))
+                .collect(Collectors.toList());
+
+    syncPublicUpdatedElements(context, elementContext, updatedPublicSyncStates,
+        publicSyncStateById, privateSyncStateById, syncedElements);
+
+    List<SynchronizationStateEntity> onlyOnPrivatePublishedSyncStates =
+        privateSyncStates.stream()
+            .filter(syncState -> !publicSyncStateById.containsKey(syncState.getId()) &&
+                syncState.getPublishTime() != null)
+            .collect(Collectors.toList());
+
+    syncPublicDeletedElements(context, elementContext, onlyOnPrivatePublishedSyncStates,
+        publicSyncStateById, privateSyncStateById, syncedElements);
+  }
+
+  private void syncPublicUpdatedElements(SessionContext context, ElementContext elementContext,
+                                         Collection<SynchronizationStateEntity> updatedPublicSyncStates,
+                                         Map<Id, SynchronizationStateEntity> publicSyncStateById,
+                                         Map<Id, SynchronizationStateEntity> privateSyncStateById,
+                                         Set<Id> syncedElements) {
+    for (SynchronizationStateEntity publicSyncState : updatedPublicSyncStates) {
+      if (syncedElements.contains(publicSyncState.getId())) {
+        continue;
+      }
+
+      ElementEntity publicElement =
+          elementPublicStore.get(context, elementContext, publicSyncState.getId()).orElseThrow(
+              () -> new IllegalStateException(String
+                  .format(PUBLIC_SYNC_STATE_EXISTS_WITHOUT_ELEMENT,
+                      elementContext.getItemId().getValue(),
+                      elementContext.getVersionId().getValue(),
+                      publicSyncState.getId().getValue())));
+
+      SynchronizationStateEntity privateSyncState =
+          privateSyncStateById.get(publicSyncState.getId());
+
+      if (privateSyncState != null) {
+        if (!privateSyncState.isDirty()) {
+          // not changed on private
+          stageElement(context, elementContext, publicElement,
+              publicSyncState.getPublishTime(),
+              Action.UPDATE, false, null);
+          syncedElements.add(publicSyncState.getId());
+        } else {
+          Optional<ElementEntity> privateElement =
+              elementPrivateStore.get(context, elementContext, publicSyncState.getId());
+
+          if (privateElement.isPresent()) {
+            // updated on private - conflict if it has different hash
+            stageElement(context, elementContext, publicElement,
+                publicSyncState.getPublishTime(), Action.UPDATE,
+                !publicElement.getElementHash().equals(privateElement.get().getElementHash()),
+                null);
+
+            syncedElements.add(publicSyncState.getId());
+          } else {
+            // deleted on private - conflict tree
+            Set<Id> changeTreeElementIds =
+                stagePublicElementTree(context, elementContext, publicElement, publicSyncStateById,
+                    (treeElementIds) -> true);
+            syncedElements.addAll(changeTreeElementIds);
+          }
+        }
+      } else {
+        // not existing on private - new creation on public
+        Set<Id> changeTreeElementIds =
+            stagePublicElementTree(context, elementContext, publicElement, publicSyncStateById,
+                (treeElementIds) -> containsDirty(treeElementIds, privateSyncStateById));
+        syncedElements.addAll(changeTreeElementIds);
+      }
+    }
+  }
+
+  private void syncPublicDeletedElements(
+      SessionContext context, ElementContext elementContext,
+      Collection<SynchronizationStateEntity> onlyOnPrivatePublishedSyncStates,
+      Map<Id, SynchronizationStateEntity> publicSyncStateById,
+      Map<Id, SynchronizationStateEntity> privateSyncStateById,
+      Set<Id> syncedElements) {
+    for (SynchronizationStateEntity privateSyncState : onlyOnPrivatePublishedSyncStates) {
+      if (syncedElements.contains(privateSyncState.getId())) {
+        continue;
+      }
+
+      Optional<ElementEntity> privateElement =
+          elementPrivateStore.get(context, elementContext, privateSyncState.getId());
+
+      if (!privateElement.isPresent()) {
+        // deleted on private as well
+        stageElement(context, elementContext, new ElementEntity(privateSyncState.getId()),
+            null, Action.DELETE, false, null);
+        syncedElements.add(privateSyncState.getId());
+      } else {
+        Set<Id> changeTreeElementIds =
+            stageElementTree(context, elementContext, privateElement.get(),
+                elementPrivateStore, publicSyncStateById::containsKey,
+                (treeElementIds) -> containsDirty(treeElementIds, privateSyncStateById),
+                (elementId) -> null, Action.DELETE);
+        syncedElements.addAll(changeTreeElementIds);
+      }
+    }
+  }
+
+  private void forceSyncDirtyElements(SessionContext context, ElementContext elementContext,
+                                      List<SynchronizationStateEntity> dirtyPrivateSyncStates,
+                                      Map<Id, SynchronizationStateEntity> publicSyncStateById,
+                                      Set<Id> syncedElements) {
+    for (SynchronizationStateEntity privateSyncState : dirtyPrivateSyncStates) {
+      Optional<ElementEntity> privateElement =
+          elementPrivateStore.get(context, elementContext, privateSyncState.getId());
+      if (privateSyncState.getPublishTime() == null) {
+        stageElement(context, elementContext,
+            privateElement.orElseThrow(() -> new IllegalStateException(
+                String.format(PRIVATE_UNPUBLISHED_SYNC_STATE_EXISTS_WITHOUT_ELEMENT,
+                    elementContext.getItemId().getValue(),
+                    elementContext.getVersionId().getValue(),
+                    privateSyncState.getId().getValue()))),
+            null, Action.DELETE, false, null);
+      } else {
+        SynchronizationStateEntity publicSyncState =
+            publicSyncStateById.get(privateSyncState.getId());
+        if (publicSyncState != null) {
+          ElementEntity publicElement =
+              elementPublicStore.get(context, elementContext, privateSyncState.getId()).orElseThrow(
+                  () -> new IllegalStateException(String
+                      .format(PUBLIC_SYNC_STATE_EXISTS_WITHOUT_ELEMENT,
+                          elementContext.getItemId().getValue(),
+                          elementContext.getVersionId().getValue(),
+                          privateSyncState.getId().getValue())));
+
+          stageElement(context, elementContext, publicElement, publicSyncState.getPublishTime(),
+              privateElement.isPresent() ? Action.UPDATE : Action.CREATE, false, null);
+        } else {
+          stageElement(context, elementContext, privateElement.isPresent()
+                  ? privateElement.get()
+                  : new ElementEntity(privateSyncState.getId()),
+              null, Action.DELETE, false, null);
+        }
+      }
+      syncedElements.add(privateSyncState.getId());
+    }
+  }
+
+  private Set<Id> stagePublicElementTree(SessionContext context,
+                                         ElementContext elementContext,
+                                         ElementEntity publicElement,
+                                         Map<Id, SynchronizationStateEntity> publicSyncStateById,
+                                         Predicate<Set<Id>> isElementTreeConflicted) {
+
+
+    return stageElementTree(context, elementContext, publicElement,
+        elementPublicStore,
+        (elementId) -> elementPrivateStore.getDescriptor(context, elementContext, elementId)
+            .isPresent(),
+        isElementTreeConflicted,
+        (elementId) -> publicSyncStateById.get(elementId).getPublishTime(),
+        Action.CREATE);
+  }
+
+  private Set<Id> stageElementTree(SessionContext context, ElementContext elementContext,
+                                   ElementEntity element,
+                                   ElementStore elementStore,
+                                   Predicate<Id> isElementExist,
+                                   Predicate<Set<Id>> isElementTreeConflicted,
+                                   Function<Id, Date> stagePublishTimeGetter,
+                                   Action stageAction) {
+    ElementEntity elementTreeRoot = findRootElementOfChange(context, elementContext,
+        elementStore, isElementExist, element);
+
+    Set<Id> elementTreeIds = new HashSet<>();
+    elementTreeIds.add(elementTreeRoot.getId());
+
+    Set<Id> subElementIds = stageElementSubs(context, elementContext, elementStore, elementTreeRoot,
+        stagePublishTimeGetter, stageAction);
+    elementTreeIds.addAll(subElementIds);
+
+    boolean conflicted = isElementTreeConflicted.test(elementTreeIds);
+    stageElement(context, elementContext, elementTreeRoot,
+        stagePublishTimeGetter.apply(elementTreeRoot.getId()), stageAction, conflicted,
+        conflicted ? subElementIds : null);
+    return elementTreeIds;
+  }
+
+  private ElementEntity findRootElementOfChange(SessionContext context,
+                                                ElementContext elementContext,
+                                                ElementStore elementStore,
+                                                Predicate<Id> isElementExistOnOppositeStore,
+                                                ElementEntity element) {
+    return element.getId().equals(ROOT_ELEMENTS_PARENT_ID) ||
+        isElementExistOnOppositeStore.test(element.getParentId())
+        ? element
+        : findRootElementOfChange(context, elementContext, elementStore,
+            isElementExistOnOppositeStore,
+            elementStore.get(context, elementContext, element.getParentId())
+                .orElseThrow(() -> new IllegalStateException(
+                    String.format("Element %s exists while its parent element %s does not",
+                        element.getId(), element.getParentId()))));
+  }
+
+  private boolean containsDirty(Set<Id> elementIds,
+                                Map<Id, SynchronizationStateEntity> syncStateById) {
+    return elementIds.stream().anyMatch(elementId -> {
+      SynchronizationStateEntity privateSyncState = syncStateById.get(elementId);
+      return privateSyncState != null && privateSyncState.isDirty();
+    });
+  }
+
+  private Set<Id> stageElementSubs(SessionContext context, ElementContext elementContext,
+                                   ElementStore elementStore, ElementEntity parentElement,
+                                   Function<Id, Date> stagePublishTimeGetter, Action stageAction) {
+    Set<Id> elementTreeIds = new HashSet<>();
+    for (Id elementId : parentElement.getSubElementIds()) {
+      ElementEntity element = elementStore.get(context, elementContext, elementId).get();
+
+      stageElement(context, elementContext, element, stagePublishTimeGetter.apply(elementId),
+          stageAction, false, null);
+
+      elementTreeIds.add(elementId);
+      elementTreeIds.addAll(
+          stageElementSubs(context, elementContext, elementStore, element, stagePublishTimeGetter,
+              stageAction));
+    }
+    return elementTreeIds;
+  }
+
+  private void stageElement(SessionContext context, ElementContext elementContext,
+                            ElementEntity element, Date publishTime, Action action,
+                            boolean conflicted, Set<Id> conflictDependents) {
+    StageEntity<ElementEntity> elementStage =
+        new StageEntity<>(element, publishTime, action, conflicted);
+    if (conflictDependents != null) {
+      elementStage.setConflictDependents(
+          conflictDependents.stream().map(ElementEntity::new).collect(Collectors.toSet()));
+    }
+    elementStageStore.create(context, elementContext, elementStage);
+  }
+
+  private void stageVersion(SessionContext context, Id itemId, VersionEntity stageVersion,
+                            Action stageAction, Date publishTime) {
+    versionStageStore
+        .create(context, itemId, new StageEntity<>(stageVersion, publishTime, stageAction, false));
+  }
+
+  private Map<Id, SynchronizationStateEntity> toMapById(
+      Collection<SynchronizationStateEntity> syncStates) {
+    return syncStates.stream()
+        .collect(Collectors.toMap(SynchronizationStateEntity::getId, Function.identity()));
+  }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/VersionCollaborationStore.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/VersionCollaborationStore.java
deleted file mode 100644
index db3066c..0000000
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/VersionCollaborationStore.java
+++ /dev/null
@@ -1,110 +0,0 @@
-package org.openecomp.core.zusammen.plugin.collaboration;
-
-import com.amdocs.zusammen.datatypes.Id;
-import com.amdocs.zusammen.datatypes.SessionContext;
-import com.amdocs.zusammen.datatypes.Space;
-import com.amdocs.zusammen.datatypes.item.Action;
-import com.amdocs.zusammen.datatypes.itemversion.Tag;
-import com.amdocs.zusammen.plugin.statestore.cassandra.dao.types.ElementEntityContext;
-import com.amdocs.zusammen.sdk.collaboration.types.CollaborationElementChange;
-import com.amdocs.zusammen.sdk.collaboration.types.CollaborationMergeChange;
-import org.openecomp.core.zusammen.plugin.ZusammenPluginUtil;
-import org.openecomp.core.zusammen.plugin.dao.ElementRepository;
-import org.openecomp.core.zusammen.plugin.dao.ElementRepositoryFactory;
-import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import static org.openecomp.core.zusammen.plugin.ZusammenPluginConstants.ROOT_ELEMENTS_PARENT_ID;
-import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.getSpaceName;
-
-public class VersionCollaborationStore {
-
-  public void tagItemVersion(SessionContext context, Id itemId, Id versionId, Id changeId,
-                             Tag tag) {
-    if (changeId != null) {
-      throw new UnsupportedOperationException(
-          "In this plugin implementation tag is supported only on versionId");
-    }
-    String space = getSpaceName(context, Space.PRIVATE);
-    ElementEntityContext targetContext = new ElementEntityContext(space, itemId, versionId);
-    targetContext.setChangeRef(tag.getName());
-    copyElements(context, new ElementEntityContext(space, itemId, versionId), targetContext,
-        getElementRepository(context));
-  }
-
-  public CollaborationMergeChange resetItemVersionHistory(SessionContext context, Id itemId,
-                                                          Id versionId, String changeRef) {
-    ElementRepository elementRepository = getElementRepository(context);
-
-    String spaceName = getSpaceName(context, Space.PRIVATE);
-    ElementEntityContext versionContext = new ElementEntityContext(spaceName, itemId, versionId);
-
-    Collection<ElementEntity> deletedElements =
-        deleteElements(context, versionContext, elementRepository);
-
-    ElementEntityContext changeRefContext = new ElementEntityContext(spaceName, itemId, versionId);
-    changeRefContext.setChangeRef(changeRef);
-
-    Collection<ElementEntity> createdElements =
-        copyElements(context, changeRefContext, versionContext, elementRepository);
-
-    // TODO: 4/19/2017 version change...
-    return createCollaborationMergeChange(versionContext, deletedElements, createdElements);
-  }
-
-  private Collection<ElementEntity> deleteElements(SessionContext context,
-                                                   ElementEntityContext elementContext,
-                                                   ElementRepository elementRepository) {
-    Collection<ElementEntity> elements = elementRepository.list(context, elementContext);
-    elements.forEach(element -> elementRepository
-        .delete(context, elementContext, new ElementEntity(element.getId())));
-    elementRepository.delete(context, elementContext, new ElementEntity(ROOT_ELEMENTS_PARENT_ID));
-    return elements;
-  }
-
-  private Collection<ElementEntity> copyElements(SessionContext context,
-                                                 ElementEntityContext sourceElementContext,
-                                                 ElementEntityContext targetElementContext,
-                                                 ElementRepository elementRepository) {
-    Collection<ElementEntity> elements = elementRepository.list(context, sourceElementContext);
-    elements.forEach(elementEntity ->
-        elementRepository.create(context, targetElementContext, elementEntity));
-    return elements;
-  }
-
-  private CollaborationMergeChange createCollaborationMergeChange(
-      ElementEntityContext versionContext,
-      Collection<ElementEntity> deletedElements,
-      Collection<ElementEntity> createdElements) {
-    CollaborationMergeChange mergeChange = new CollaborationMergeChange();
-    mergeChange.getChangedElements().addAll(
-        convertToCollaborationElementChanges(versionContext, deletedElements, Action.DELETE));
-    mergeChange.getChangedElements().addAll(
-        convertToCollaborationElementChanges(versionContext, createdElements, Action.CREATE));
-    return mergeChange;
-  }
-
-  private List<CollaborationElementChange> convertToCollaborationElementChanges(
-      ElementEntityContext elementContext, Collection<ElementEntity> changedElements,
-      Action action) {
-    return changedElements.stream()
-        .map(element -> convertToCollaborationElementChange(element, elementContext, action))
-        .collect(Collectors.toList());
-  }
-
-  private CollaborationElementChange convertToCollaborationElementChange(
-      ElementEntity elementEntity, ElementEntityContext elementContext, Action action) {
-    CollaborationElementChange elementChange = new CollaborationElementChange();
-    elementChange
-        .setElement(ZusammenPluginUtil.getCollaborationElement(elementContext, elementEntity));
-    elementChange.setAction(action);
-    return elementChange;
-  }
-
-  protected ElementRepository getElementRepository(SessionContext context) {
-    return ElementRepositoryFactory.getInstance().createInterface(context);
-  }
-}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/VersionPrivateStore.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/VersionPrivateStore.java
new file mode 100644
index 0000000..a024327
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/VersionPrivateStore.java
@@ -0,0 +1,38 @@
+package org.openecomp.core.zusammen.plugin.collaboration;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import org.openecomp.core.zusammen.plugin.dao.types.SynchronizationStateEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
+
+import java.util.Date;
+import java.util.Optional;
+
+public interface VersionPrivateStore {
+  Optional<VersionEntity> get(SessionContext context, Id itemId, Id versionId);
+
+  Optional<SynchronizationStateEntity> getSynchronizationState(SessionContext context, Id itemId,
+                                                               Id versionId);
+
+  void create(SessionContext context, Id itemId, VersionEntity version);
+
+  void update(SessionContext context, Id itemId, VersionEntity version);
+
+  void update(SessionContext context, Id itemId, VersionEntity version, Date publishTime,
+              boolean dirty);
+
+  void delete(SessionContext context, Id itemId, VersionEntity version);
+
+  void markAsPublished(SessionContext context, Id itemId, Id versionId, Date publishTime);
+
+  void commitStagedCreate(SessionContext context, Id itemId, VersionEntity version,
+                          Date publishTime);
+
+  void commitStagedUpdate(SessionContext context, Id itemId, VersionEntity version,
+                          Date publishTime);
+
+  void commitStagedIgnore(SessionContext context, Id itemId, VersionEntity version,
+                          Date publishTime);
+
+
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/VersionPublicStore.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/VersionPublicStore.java
new file mode 100644
index 0000000..c86db0e
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/VersionPublicStore.java
@@ -0,0 +1,29 @@
+package org.openecomp.core.zusammen.plugin.collaboration;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.itemversion.ItemVersionRevisions;
+import org.openecomp.core.zusammen.plugin.dao.types.SynchronizationStateEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
+
+import java.util.Date;
+import java.util.Map;
+import java.util.Optional;
+
+public interface VersionPublicStore {
+
+  Optional<VersionEntity> get(SessionContext context, Id itemId, Id versionId);
+
+  Optional<SynchronizationStateEntity> getSynchronizationState(SessionContext context,
+                                                               Id itemId, Id versionId);
+
+  void create(SessionContext context, Id itemId, VersionEntity version, Id revisionId,
+              Map<Id, Id> versionElementIds, Date publishTime, String message);
+
+  void update(SessionContext context, Id itemId, VersionEntity version, Id revisionId,
+              Map<Id, Id> versionElementIds, Date publishTime, String message);
+
+  boolean checkHealth(SessionContext context);
+
+  ItemVersionRevisions listItemVersionRevisions(SessionContext context, Id itemId, Id versionId);
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/VersionStageStore.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/VersionStageStore.java
new file mode 100644
index 0000000..5058a26
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/VersionStageStore.java
@@ -0,0 +1,18 @@
+package org.openecomp.core.zusammen.plugin.collaboration;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import org.openecomp.core.zusammen.plugin.dao.types.StageEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
+
+import java.util.Optional;
+
+public interface VersionStageStore {
+
+  Optional<StageEntity<VersionEntity>> get(SessionContext context, Id itemId,
+                                           VersionEntity versionEntity);
+
+  void create(SessionContext context, Id itemId, StageEntity<VersionEntity> versionStage);
+
+  void delete(SessionContext context, Id itemId, VersionEntity version);
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/ElementPrivateStoreImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/ElementPrivateStoreImpl.java
new file mode 100644
index 0000000..9f54ee3
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/ElementPrivateStoreImpl.java
@@ -0,0 +1,269 @@
+package org.openecomp.core.zusammen.plugin.collaboration.impl;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.item.ElementContext;
+import com.amdocs.zusammen.plugin.statestore.cassandra.dao.types.ElementEntityContext;
+import org.openecomp.core.zusammen.plugin.ZusammenPluginConstants;
+import org.openecomp.core.zusammen.plugin.collaboration.ElementPrivateStore;
+import org.openecomp.core.zusammen.plugin.dao.ElementRepository;
+import org.openecomp.core.zusammen.plugin.dao.ElementRepositoryFactory;
+import org.openecomp.core.zusammen.plugin.dao.ElementSynchronizationStateRepository;
+import org.openecomp.core.zusammen.plugin.dao.ElementSynchronizationStateRepositoryFactory;
+import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.SynchronizationStateEntity;
+
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.getPrivateElementContext;
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.getPrivateSpaceName;
+
+public class ElementPrivateStoreImpl implements ElementPrivateStore {
+  private static final Id REVISION_ID = Id.ZERO; // the private revision id is Id.ZERO 0000000...
+
+  @Override
+  public Map<Id, Id> listIds(SessionContext context, ElementContext elementContext) {
+    return getElementRepository(context)
+        .listIds(context, new ElementEntityContext(getPrivateSpaceName(context), elementContext));
+  }
+
+  @Override
+  public Collection<ElementEntity> listSubs(SessionContext context, ElementContext elementContext,
+                                            Id elementId) {
+    if (elementId == null) {
+      elementId = ZusammenPluginConstants.ROOT_ELEMENTS_PARENT_ID;
+    }
+
+    ElementRepository elementRepository = getElementRepository(context);
+    ElementEntityContext privateContext =
+        new ElementEntityContext(getPrivateSpaceName(context), elementContext);
+    privateContext.setRevisionId(REVISION_ID);
+    return elementRepository.get(context, privateContext, new ElementEntity(elementId))
+        .map(ElementEntity::getSubElementIds).orElse(new HashSet<>()).stream()
+        .map(subElementId -> elementRepository
+            .get(context, privateContext, new ElementEntity(subElementId)).get())
+        .filter(Objects::nonNull)
+        .collect(Collectors.toList());
+  }
+
+  @Override
+  public Optional<ElementEntity> get(SessionContext context, ElementContext elementContext,
+                                     Id elementId) {
+    ElementEntityContext privateElementContext =
+        new ElementEntityContext(getPrivateSpaceName(context), elementContext);
+    privateElementContext.setRevisionId(REVISION_ID);
+    return getElementRepository(context)
+        .get(context, privateElementContext,
+            new ElementEntity(elementId));
+  }
+
+  @Override
+  public Optional<ElementEntity> getDescriptor(SessionContext context,
+                                               ElementContext elementContext, Id elementId) {
+    return getElementRepository(context)
+        .getDescriptor(context,
+            new ElementEntityContext(getPrivateSpaceName(context), getPrivateElementContext
+                (elementContext)),
+            new ElementEntity(elementId));
+  }
+
+  @Override
+  public Collection<SynchronizationStateEntity> listSynchronizationStates(SessionContext context,
+                                                                          ElementContext elementContext) {
+    ElementEntityContext privateElementContext =
+        new ElementEntityContext(getPrivateSpaceName(context), elementContext);
+    return getElementSyncStateRepository(context)
+        .list(context, privateElementContext);
+  }
+
+  @Override
+  public Optional<SynchronizationStateEntity> getSynchronizationState(SessionContext context,
+                                                                      ElementContext elementContext,
+                                                                      Id elementId) {
+
+    ElementEntityContext privateElementContext =
+        new ElementEntityContext(getPrivateSpaceName(context), getPrivateElementContext
+            (elementContext));
+    return getElementSyncStateRepository(context)
+        .get(context, privateElementContext,
+            new SynchronizationStateEntity(elementId, REVISION_ID));
+  }
+
+  @Override
+  public void create(SessionContext context, ElementContext elementContext, ElementEntity element) {
+    create(context, elementContext, element, true, null);
+  }
+
+  @Override
+  public boolean update(SessionContext context, ElementContext elementContext,
+                        ElementEntity element) {
+    ElementEntityContext privateContext =
+        new ElementEntityContext(getPrivateSpaceName(context), elementContext);
+    privateContext.setRevisionId(REVISION_ID);
+
+    if (!isElementChanged(context, privateContext, element)) {
+      return false;
+    }
+
+    getElementRepository(context).update(context, privateContext, element);
+    getElementSyncStateRepository(context).markAsDirty(context, privateContext,
+        new SynchronizationStateEntity(element.getId(), REVISION_ID));
+    return true;
+  }
+
+  @Override
+  public void delete(SessionContext context, ElementContext elementContext, ElementEntity element) {
+
+    ElementEntityContext privateElementContext =
+        new ElementEntityContext(getPrivateSpaceName(context), elementContext);
+    privateElementContext.setRevisionId(REVISION_ID);
+    deleteElementHierarchy(context, getElementRepository(context),
+        getElementSyncStateRepository(context),
+        privateElementContext, element);
+  }
+
+  @Override
+  public void markAsPublished(SessionContext context, ElementContext elementContext, Id elementId,
+                              Date publishTime) {
+    ElementEntityContext privateContext =
+        new ElementEntityContext(getPrivateSpaceName(context), elementContext);
+    privateContext.setRevisionId(REVISION_ID);
+    getElementSyncStateRepository(context).update(context,
+        privateContext,
+        new SynchronizationStateEntity(elementId, REVISION_ID, publishTime, false));
+  }
+
+  @Override
+  public void markDeletionAsPublished(SessionContext context, ElementContext elementContext,
+                                      Id elementId, Date publishTime) {
+
+    ElementEntityContext privateContext =
+        new ElementEntityContext(getPrivateSpaceName(context), elementContext);
+    privateContext.setRevisionId(REVISION_ID);
+    getElementSyncStateRepository(context).delete(context,
+        privateContext,
+        new SynchronizationStateEntity(elementId, REVISION_ID));
+  }
+
+  @Override
+  public void commitStagedCreate(SessionContext context, ElementContext elementContext,
+                                 ElementEntity element, Date publishTime) {
+    create(context, elementContext, element, false, publishTime);
+  }
+
+  @Override
+  public void commitStagedUpdate(SessionContext context, ElementContext elementContext,
+                                 ElementEntity element, Date publishTime) {
+    ElementEntityContext privateContext =
+        new ElementEntityContext(getPrivateSpaceName(context), elementContext);
+    privateContext.setRevisionId(REVISION_ID);
+
+    getElementRepository(context).update(context, privateContext, element);
+    // Currently Resolution='Other' is not supported so this is invoked after conflict was
+    // resolved with Resolution='Theirs' so dirty flag should be turned off.
+    // (if there was no conflict it's off anyway)
+    getElementSyncStateRepository(context).update(context, privateContext,
+        new SynchronizationStateEntity(element.getId(), REVISION_ID, publishTime, false));
+  }
+
+  @Override
+  public void commitStagedDelete(SessionContext context, ElementContext elementContext,
+                                 ElementEntity element) {
+    ElementEntityContext privateContext =
+        new ElementEntityContext(getPrivateSpaceName(context), elementContext);
+    privateContext.setRevisionId(REVISION_ID);
+    getElementRepository(context).delete(context, privateContext, element);
+    getElementSyncStateRepository(context)
+        .delete(context, privateContext,
+            new SynchronizationStateEntity(element.getId(), REVISION_ID));
+  }
+
+  @Override
+  public void commitStagedIgnore(SessionContext context, ElementContext elementContext,
+                                 ElementEntity element, Date publishTime) {
+    // publish time - updated to mark that this element was already synced with this publish time
+    // (even though the local data was preferred) and to prevent this conflict again.
+    // dirty - turned on because the local data which is different than the public one was
+    // preferred. It will enable future publication of this data.
+    getElementSyncStateRepository(context).update(context,
+        new ElementEntityContext(getPrivateSpaceName(context), elementContext),
+        new SynchronizationStateEntity(element.getId(), REVISION_ID, publishTime, true));
+  }
+
+  private void create(SessionContext context, ElementContext elementContext,
+                      ElementEntity element, boolean dirty, Date publishTime) {
+    ElementEntityContext privateContext =
+        new ElementEntityContext(getPrivateSpaceName(context), elementContext);
+    privateContext.setRevisionId(REVISION_ID);
+    getElementRepository(context).create(context, privateContext, element);
+    getElementSyncStateRepository(context).create(context, privateContext,
+        new SynchronizationStateEntity(element.getId(), REVISION_ID, publishTime, dirty));
+  }
+
+
+  private void deleteElementHierarchy(
+      SessionContext context, ElementRepository elementRepository,
+      ElementSynchronizationStateRepository elementSyncStateRepository,
+      ElementEntityContext elementContext, ElementEntity element) {
+
+    Optional<ElementEntity> retrieved = elementRepository.get(context, elementContext, element);
+    if (!retrieved.isPresent()) {
+      return;
+    }
+    retrieved.get().getSubElementIds().stream()
+        .map(ElementEntity::new)
+        .forEach(subElementEntity -> deleteElementHierarchy(
+            context, elementRepository, elementSyncStateRepository, elementContext,
+            subElementEntity));
+
+    // only for the first one the parentId will populated (so it'll be removed from its parent)
+    elementRepository.delete(context, elementContext, element);
+    handleDeletedElementSyncState(context, elementSyncStateRepository, elementContext, element);
+  }
+
+  private void handleDeletedElementSyncState(SessionContext context,
+                                             ElementSynchronizationStateRepository elementSyncStateRepository,
+                                             ElementEntityContext elementContext,
+                                             ElementEntity element) {
+    SynchronizationStateEntity elementSyncState = new SynchronizationStateEntity(element.getId(),
+        REVISION_ID);
+    if (elementSyncStateRepository.get(context, elementContext, elementSyncState).
+        orElseThrow(
+            () -> new IllegalStateException("Synchronization state must exist for an element"))
+        .getPublishTime() == null) {
+      elementSyncStateRepository.delete(context, elementContext, elementSyncState);
+    } else {
+      elementSyncStateRepository.markAsDirty(context, elementContext, elementSyncState);
+    }
+  }
+
+  private boolean isElementChanged(SessionContext context,
+                                   ElementEntityContext elementContext,
+                                   ElementEntity newElement) {
+    return getElementHash(context, elementContext, new ElementEntity(newElement.getId()))
+        .map(existingHash -> !newElement.getElementHash().equals(existingHash))
+        .orElse(true);
+  }
+
+  private Optional<Id> getElementHash(SessionContext context,
+                                      ElementEntityContext elementEntityContext,
+                                      ElementEntity element) {
+    return getElementRepository(context).getHash(context, elementEntityContext, element);
+  }
+
+  protected ElementRepository getElementRepository(SessionContext context) {
+    return ElementRepositoryFactory.getInstance().createInterface(context);
+  }
+
+  protected ElementSynchronizationStateRepository getElementSyncStateRepository(
+      SessionContext context) {
+    return ElementSynchronizationStateRepositoryFactory.getInstance().createInterface(context);
+  }
+
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/ElementPublicStoreImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/ElementPublicStoreImpl.java
new file mode 100644
index 0000000..d946a52
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/ElementPublicStoreImpl.java
@@ -0,0 +1,189 @@
+package org.openecomp.core.zusammen.plugin.collaboration.impl;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.Space;
+import com.amdocs.zusammen.datatypes.item.ElementContext;
+import com.amdocs.zusammen.plugin.statestore.cassandra.dao.types.ElementEntityContext;
+import org.openecomp.core.zusammen.plugin.collaboration.ElementPublicStore;
+import org.openecomp.core.zusammen.plugin.dao.ElementRepository;
+import org.openecomp.core.zusammen.plugin.dao.ElementRepositoryFactory;
+import org.openecomp.core.zusammen.plugin.dao.ElementSynchronizationStateRepository;
+import org.openecomp.core.zusammen.plugin.dao.ElementSynchronizationStateRepositoryFactory;
+import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.SynchronizationStateEntity;
+
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Optional;
+
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.getSpaceName;
+
+public class ElementPublicStoreImpl implements ElementPublicStore {
+
+  @Override
+  public Optional<ElementEntity> get(SessionContext context,
+                                     ElementContext elementContext, Id elementId) {
+    return getElementRepository(context)
+        .get(context, new ElementEntityContext(getSpaceName(context, Space.PUBLIC), elementContext),
+            new ElementEntity(elementId));
+  }
+
+  @Override
+  public Optional<ElementEntity> getDescriptor(SessionContext context,
+                                               ElementContext elementContext, Id elementId) {
+    return getElementRepository(context).getDescriptor(context,
+        new ElementEntityContext(getSpaceName(context, Space.PUBLIC), elementContext),
+        new ElementEntity(elementId));
+  }
+
+  @Override
+  public Collection<SynchronizationStateEntity> listSynchronizationStates(
+      SessionContext context, ElementContext elementContext) {
+    ElementEntityContext entityContext = new ElementEntityContext(getSpaceName
+        (context, Space.PUBLIC), elementContext);
+
+    ElementSynchronizationStateRepository elementSyncStateRepository =
+        getElementSyncStateRepository(context);
+    Map<Id, Id> ids = getElementRepository(context).listIds(context, entityContext);
+
+    Collection<SynchronizationStateEntity> synchronizationStateEntities = new HashSet<>();
+    for (Map.Entry<Id, Id> elementEntry : ids.entrySet()) {
+      Optional<SynchronizationStateEntity> synchronizationStateEntity = elementSyncStateRepository.
+          get(context, entityContext, new SynchronizationStateEntity(elementEntry.getKey(),
+              elementEntry.getValue()));
+      if (synchronizationStateEntity.isPresent()) {
+        synchronizationStateEntities.add(synchronizationStateEntity.get());
+      } else {
+        /*throw new IllegalStateException(String.format(
+            "list Synchronization States error: " + "element %s revision %s, which appears as an " +
+                "element of " +
+                "item" +
+                " %s version %s, does not exist",
+            elementEntry.getKey(), elementEntry.getValue(), elementContext.getItemId().getValue(),
+            elementContext.getVersionId().getValue()));*/
+      }
+    }
+
+    return synchronizationStateEntities;
+  }
+
+  @Override
+  public void create(SessionContext context, ElementContext elementContext,
+                     ElementEntity element, Date publishTime) {
+    ElementEntityContext publicContext =
+        new ElementEntityContext(getSpaceName(context, Space.PUBLIC), elementContext);
+
+
+    if (element.getParentId() != null) {
+      createParentElement(context, elementContext, element.getParentId(), publishTime);
+    }
+    getElementRepository(context).create(context, publicContext, element);
+    getElementSyncStateRepository(context).create(context, publicContext,
+        new SynchronizationStateEntity(element.getId(), elementContext.getRevisionId(),
+            publishTime, false));
+  }
+
+  @Override
+  public void update(SessionContext context, ElementContext elementContext,
+                     ElementEntity element, Date publishTime) {
+    //todo - update in public should be create new entry with new revision_id in public - this is a
+    // new revision
+    ElementEntityContext publicContext =
+        new ElementEntityContext(getSpaceName(context, Space.PUBLIC), elementContext);
+
+    Optional<ElementEntity> publicElement = getElementRepository(context).get(context,
+        publicContext, new ElementEntity(element.getId()));
+    if (publicElement.isPresent()) {
+      getElementRepository(context).update(context, publicContext, element);
+    } else {
+       publicElement = get(context,new ElementContext(publicContext.getItemId(),publicContext
+           .getVersionId()),element.getId());
+       element.setSubElementIds(publicElement.get().getSubElementIds());
+      getElementRepository(context).create(context, publicContext, element);
+    }
+    getElementSyncStateRepository(context).update(context, publicContext,
+        new SynchronizationStateEntity(element.getId(), elementContext.getRevisionId(), publishTime,
+            false));
+  }
+
+  @Override
+  public void delete(SessionContext context, ElementContext elementContext,
+                     ElementEntity element, Date publishTime) {
+    ElementEntityContext publicContext =
+        new ElementEntityContext(getSpaceName(context, Space.PUBLIC), elementContext);
+
+    if (element.getParentId() != null) {
+      Optional<ElementEntity> parentElement = get(context, elementContext, element.getParentId());
+      if (parentElement.isPresent()) {
+        createParentElement(context, elementContext, element.getParentId(), publishTime);
+      }
+    }
+
+    getElementRepository(context).delete(context, publicContext, element);
+    getElementSyncStateRepository(context)
+        .delete(context, publicContext, new SynchronizationStateEntity(element.getId(),
+            elementContext.getRevisionId()));
+  }
+
+  @Override
+  public Map<Id, Id> listIds(SessionContext context, ElementContext elementContext) {
+
+    return getElementRepository(context)
+        .listIds(context,
+            new ElementEntityContext(getSpaceName(context, Space.PUBLIC), elementContext));
+
+  }
+
+  private void createParentElement(SessionContext context, ElementContext elementContext,
+                                   Id parentElementId, Date publishTime
+  ) {
+    ElementEntityContext publicContext =
+        new ElementEntityContext(getSpaceName(context, Space.PUBLIC), elementContext);
+
+    Optional<ElementEntity> parentElement =
+        getElementRepository(context).get(context, new ElementEntityContext
+                (publicContext.getSpace(), publicContext.getItemId(), publicContext.getVersionId(),
+                    elementContext.getRevisionId()),
+            new ElementEntity(parentElementId));
+    if(parentElement.isPresent()) {
+      update(context, elementContext, parentElement.get(), publishTime);
+    }
+
+
+   /* Id elementRevisionId = getElementRevision(context, publicContext, elementContext.getRevisionId()
+        , parentElementId);
+
+    if (elementRevisionId != null && !elementRevisionId.equals(elementContext.getRevisionId())) {
+      Optional<ElementEntity> parentElement =
+          getElementRepository(context).get(context, new ElementEntityContext
+                  (publicContext.getSpace(), publicContext.getItemId(), publicContext.getVersionId(),
+                      elementContext.getRevisionId()),
+              new ElementEntity(parentElementId));
+      elementRevisionId = getElementRevision(context, publicContext, elementContext.getRevisionId()
+          , parentElement.get().getId());
+      if (elementRevisionId != null) {
+        update(context, elementContext, parentElement.get(), publishTime);
+      } else {
+        create(context, elementContext, parentElement.get(), publishTime);
+      }
+
+    }*/
+  }
+
+
+
+
+  protected ElementRepository getElementRepository(SessionContext context) {
+    return ElementRepositoryFactory.getInstance().createInterface(context);
+  }
+
+  protected ElementSynchronizationStateRepository getElementSyncStateRepository(
+      SessionContext context) {
+    return ElementSynchronizationStateRepositoryFactory.getInstance().createInterface(context);
+  }
+
+
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/ElementStageStoreImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/ElementStageStoreImpl.java
new file mode 100644
index 0000000..f6c2943
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/ElementStageStoreImpl.java
@@ -0,0 +1,133 @@
+package org.openecomp.core.zusammen.plugin.collaboration.impl;
+
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.item.Action;
+import com.amdocs.zusammen.datatypes.item.ElementContext;
+import com.amdocs.zusammen.datatypes.item.Resolution;
+import com.amdocs.zusammen.plugin.statestore.cassandra.dao.types.ElementEntityContext;
+import org.openecomp.core.zusammen.plugin.collaboration.ElementStageStore;
+import org.openecomp.core.zusammen.plugin.dao.ElementStageRepository;
+import org.openecomp.core.zusammen.plugin.dao.ElementStageRepositoryFactory;
+import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.StageEntity;
+
+import java.util.Collection;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.getPrivateElementContext;
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.getPrivateSpaceName;
+
+public class ElementStageStoreImpl implements ElementStageStore {
+
+  @Override
+  public Collection<ElementEntity> listIds(SessionContext context, ElementContext elementContext) {
+    return getElementStageRepository(context)
+        .listIds(context, new ElementEntityContext(getPrivateSpaceName(context),
+            getPrivateElementContext(elementContext)));
+  }
+
+  @Override
+  public Optional<StageEntity<ElementEntity>> get(SessionContext context,
+                                                  ElementContext elementContext,
+                                                  ElementEntity element) {
+    return getElementStageRepository(context).get(context,
+        new ElementEntityContext(getPrivateSpaceName(context),
+            getPrivateElementContext(elementContext)),
+        element);
+  }
+
+  @Override
+  public Optional<StageEntity<ElementEntity>> getConflicted(SessionContext context,
+                                                            ElementContext elementContext,
+                                                            ElementEntity element) {
+    return get(context, elementContext, element).filter(StageEntity::isConflicted);
+  }
+
+  @Override
+  public boolean hasConflicts(SessionContext context, ElementContext elementContext) {
+    return !getElementStageRepository(context).listConflictedIds(context,
+        new ElementEntityContext(getPrivateSpaceName(context), getPrivateElementContext(elementContext))).isEmpty();
+  }
+
+  @Override
+  public Collection<StageEntity<ElementEntity>> listConflictedDescriptors(SessionContext context,
+                                                                          ElementContext elementContext) {
+    ElementEntityContext privateContext =
+        new ElementEntityContext(getPrivateSpaceName(context), getPrivateElementContext
+            (elementContext));
+    ElementStageRepository elementStageRepository = getElementStageRepository(context);
+
+    return elementStageRepository.listConflictedIds(context, privateContext).stream()
+        .map(conflictedElement -> elementStageRepository
+            .getDescriptor(context, privateContext, conflictedElement).get())
+        .collect(Collectors.toList());
+  }
+
+  @Override
+  public void create(SessionContext context, ElementContext elementContext,
+                     StageEntity<ElementEntity> elementStage) {
+    getElementStageRepository(context)
+        .create(context,
+            new ElementEntityContext(getPrivateSpaceName(context), getPrivateElementContext(elementContext)),
+            elementStage);
+  }
+
+  @Override
+  public void delete(SessionContext context, ElementContext elementContext, ElementEntity element) {
+    getElementStageRepository(context)
+        .delete(context,
+            new ElementEntityContext(getPrivateSpaceName(context), getPrivateElementContext(elementContext)),
+            element);
+  }
+
+
+  @Override
+  public void resolveConflict(SessionContext context, ElementContext elementContext,
+                              ElementEntity element, Resolution resolution) {
+    Optional<StageEntity<ElementEntity>> stagedElement =
+        getConflicted(context, elementContext, element);
+    if (!stagedElement.isPresent()) {
+      return;
+    }
+
+    ElementEntityContext privateContext =
+        new ElementEntityContext(getPrivateSpaceName(context), getPrivateElementContext
+            (elementContext));
+
+    switch (resolution) {
+      case YOURS:
+        resolveConflictByYours(context, privateContext, stagedElement.get());
+        break;
+      case THEIRS:
+        resolveConflictByTheirs(context, privateContext, stagedElement.get());
+        break;
+      case OTHER: // other = data updates only? no data deletions? if so, then:
+        // conflicted = false
+        // element = the input of resolve
+        // action = update
+        throw new UnsupportedOperationException("'Other' conflict resolution is not yet supported");
+      default:
+        break;
+    }
+  }
+
+  private void resolveConflictByYours(SessionContext context, ElementEntityContext privateContext,
+                                      StageEntity<ElementEntity> stagedElement) {
+    getElementStageRepository(context)
+        .markAsNotConflicted(context, privateContext, stagedElement.getEntity(), Action.IGNORE);
+    stagedElement.getConflictDependents().forEach(conflictDependant ->
+        getElementStageRepository(context)
+            .markAsNotConflicted(context, privateContext, conflictDependant, Action.IGNORE));
+  }
+
+  private void resolveConflictByTheirs(SessionContext context, ElementEntityContext privateContext,
+                                       StageEntity<ElementEntity> stagedElement) {
+    getElementStageRepository(context)
+        .markAsNotConflicted(context, privateContext, stagedElement.getEntity());
+  }
+
+  protected ElementStageRepository getElementStageRepository(SessionContext context) {
+    return ElementStageRepositoryFactory.getInstance().createInterface(context);
+  }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/VersionPrivateStoreImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/VersionPrivateStoreImpl.java
new file mode 100644
index 0000000..11e61ab
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/VersionPrivateStoreImpl.java
@@ -0,0 +1,117 @@
+package org.openecomp.core.zusammen.plugin.collaboration.impl;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import org.openecomp.core.zusammen.plugin.collaboration.VersionPrivateStore;
+import org.openecomp.core.zusammen.plugin.dao.VersionDao;
+import org.openecomp.core.zusammen.plugin.dao.VersionDaoFactory;
+import org.openecomp.core.zusammen.plugin.dao.VersionSynchronizationStateRepository;
+import org.openecomp.core.zusammen.plugin.dao.VersionSynchronizationStateRepositoryFactory;
+import org.openecomp.core.zusammen.plugin.dao.types.SynchronizationStateEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionContext;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
+
+import java.util.Date;
+import java.util.Optional;
+
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.getPrivateSpaceName;
+
+public class VersionPrivateStoreImpl implements VersionPrivateStore {
+
+  Id revisionId = Id.ZERO;
+
+  @Override
+  public Optional<VersionEntity> get(SessionContext context, Id itemId, Id versionId) {
+    return getVersionDao(context).get(context, getPrivateSpaceName(context), itemId, versionId);
+  }
+
+  @Override
+  public Optional<SynchronizationStateEntity> getSynchronizationState(SessionContext context,
+                                                                      Id itemId, Id versionId) {
+
+    return getVersionSyncStateRepository(context)
+        .get(context, new VersionContext(getPrivateSpaceName(context), itemId),
+            new SynchronizationStateEntity(versionId, revisionId));
+  }
+
+  @Override
+  public void create(SessionContext context, Id itemId, VersionEntity version) {
+    String privateSpace = getPrivateSpaceName(context);
+
+
+    getVersionDao(context).create(context, privateSpace, itemId, version);
+    getVersionSyncStateRepository(context).create(context, new VersionContext(privateSpace,
+            itemId),
+        new SynchronizationStateEntity(version.getId(), revisionId, null, true));
+  }
+
+  @Override
+  public void update(SessionContext context, Id itemId, VersionEntity version) {
+
+    getVersionDao(context)
+        .updateModificationTime(context, getPrivateSpaceName(context), itemId, version.getId(),
+            version.getModificationTime());
+  }
+
+  @Override
+  public void update(SessionContext context, Id itemId, VersionEntity version, Date publishTime,
+                     boolean dirty) {
+    getVersionSyncStateRepository(context).updatePublishTime(context,
+        new VersionContext(getPrivateSpaceName(context), itemId),
+        new SynchronizationStateEntity(version.getId(), revisionId, publishTime, dirty));
+  }
+
+  @Override
+  public void delete(SessionContext context, Id itemId, VersionEntity version) {
+    String privateSpace = getPrivateSpaceName(context);
+
+    getVersionDao(context).delete(context, privateSpace, itemId, version.getId());
+    getVersionSyncStateRepository(context).delete(context, new VersionContext(privateSpace,
+            itemId),
+        new SynchronizationStateEntity(version.getId(), revisionId));
+  }
+
+  @Override
+  public void markAsPublished(SessionContext context, Id itemId, Id versionId, Date publishTime) {
+    getVersionSyncStateRepository(context)
+        .updatePublishTime(context, new VersionContext(getPrivateSpaceName(context), itemId),
+            new SynchronizationStateEntity(versionId, revisionId, publishTime, false));
+  }
+
+  @Override
+  public void commitStagedCreate(SessionContext context, Id itemId, VersionEntity version,
+                                 Date publishTime) {
+    String privateSpace = getPrivateSpaceName(context);
+
+    getVersionDao(context).create(context, privateSpace, itemId, version);
+    getVersionSyncStateRepository(context).create(context, new VersionContext(privateSpace,
+            itemId),
+        new SynchronizationStateEntity(version.getId(), revisionId, publishTime, false));
+  }
+
+  @Override
+  public void commitStagedUpdate(SessionContext context, Id itemId, VersionEntity version,
+                                 Date publishTime) {
+    update(context, itemId, version, publishTime, false);
+  }
+
+  @Override
+  public void commitStagedIgnore(SessionContext context, Id itemId, VersionEntity version,
+                                 Date publishTime) {
+    getVersionSyncStateRepository(context).updatePublishTime(context,
+        new VersionContext(getPrivateSpaceName(context), itemId),
+        new SynchronizationStateEntity(version.getId(), revisionId, publishTime, false));
+  }
+
+
+
+
+  protected VersionDao getVersionDao(SessionContext context) {
+    return VersionDaoFactory.getInstance().createInterface(context);
+  }
+
+  protected VersionSynchronizationStateRepository getVersionSyncStateRepository(
+      SessionContext context) {
+    return VersionSynchronizationStateRepositoryFactory.getInstance().createInterface(context);
+  }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/VersionPublicStoreImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/VersionPublicStoreImpl.java
new file mode 100644
index 0000000..aa628eb
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/VersionPublicStoreImpl.java
@@ -0,0 +1,135 @@
+package org.openecomp.core.zusammen.plugin.collaboration.impl;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.Space;
+import com.amdocs.zusammen.datatypes.itemversion.ItemVersionRevisions;
+import com.amdocs.zusammen.datatypes.itemversion.Revision;
+import org.openecomp.core.zusammen.plugin.collaboration.VersionPublicStore;
+import org.openecomp.core.zusammen.plugin.dao.VersionDao;
+import org.openecomp.core.zusammen.plugin.dao.VersionDaoFactory;
+import org.openecomp.core.zusammen.plugin.dao.VersionSynchronizationStateRepository;
+import org.openecomp.core.zusammen.plugin.dao.VersionSynchronizationStateRepositoryFactory;
+import org.openecomp.core.zusammen.plugin.dao.types.SynchronizationStateEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionContext;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
+
+import java.util.Comparator;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.getSpaceName;
+
+public class VersionPublicStoreImpl implements VersionPublicStore {
+  @Override
+  public Optional<VersionEntity> get(SessionContext context, Id itemId, Id versionId) {
+    return getVersionDao(context)
+        .get(context, getSpaceName(context, Space.PUBLIC), itemId, versionId);
+  }
+
+  @Override
+  public Optional<SynchronizationStateEntity> getSynchronizationState(SessionContext context,
+                                                                      Id itemId, Id versionId) {
+    Id revisionId = getLastItemVersionRevision(context, itemId,
+        versionId);
+    if (revisionId == null) {
+      return Optional.empty();
+    }
+
+    return getVersionSyncStateRepository(context)
+        .get(context, new VersionContext(getSpaceName(context, Space.PUBLIC), itemId),
+            new SynchronizationStateEntity(versionId, revisionId));
+  }
+
+
+  @Override
+  public void create(SessionContext context, Id itemId, VersionEntity version, Id revisionId,
+                     Map<Id, Id> versionElementIds, Date
+                         publishTime, String message) {
+    String publicSpace = getSpaceName(context, Space.PUBLIC);
+
+    getVersionDao(context).create(context, publicSpace, itemId, version);
+
+    getVersionDao(context).createVersionElements(context, publicSpace, itemId, version.getId(),
+        revisionId, versionElementIds, publishTime,message);
+
+    getVersionSyncStateRepository(context).create(context, new VersionContext(publicSpace,
+            itemId),
+        new SynchronizationStateEntity(version.getId(), revisionId, publishTime, false));
+  }
+
+  @Override
+  public void update(SessionContext context, Id itemId, VersionEntity version,
+                     Id revisionId, Map<Id, Id> versionElementIds, Date publishTime, String message) {
+    String publicSpace = getSpaceName(context, Space.PUBLIC);
+
+    getVersionDao(context).
+        createVersionElements(context, publicSpace, itemId, version.getId(),
+            revisionId, versionElementIds, publishTime,message);
+
+    getVersionSyncStateRepository(context).
+        updatePublishTime(context, new VersionContext(publicSpace, itemId),
+            new SynchronizationStateEntity(version.getId(), revisionId, publishTime, false));
+  }
+
+  @Override
+  public boolean checkHealth(SessionContext context) {
+    return getVersionDao(context).checkHealth(context);
+  }
+
+  @Override
+  public ItemVersionRevisions listItemVersionRevisions(SessionContext context, Id itemId,
+                                                       Id versionId) {
+    VersionContext entityContext = new VersionContext(getSpaceName(context, Space.PUBLIC), itemId);
+    List<SynchronizationStateEntity> versionRevisions = getVersionSyncStateRepository(context)
+        .list(context, entityContext, new VersionEntity(versionId));
+
+    if (versionRevisions == null || versionRevisions.size() == 0) {
+      return null;
+    }
+
+    versionRevisions.sort(new Comparator<SynchronizationStateEntity>() {
+      @Override
+      public int compare(SynchronizationStateEntity o1, SynchronizationStateEntity o2) {
+        if (o1.getPublishTime().after(o2.getPublishTime())) {
+          return -1;
+        } else {
+          return 1;
+        }
+      }
+    });
+    ItemVersionRevisions itemVersionRevisions = new ItemVersionRevisions();
+    versionRevisions.forEach(synchronizationStateEntity -> itemVersionRevisions.addChange
+        (convertSyncState2Revision(synchronizationStateEntity)));
+    return itemVersionRevisions;
+  }
+
+  private Revision convertSyncState2Revision(
+      SynchronizationStateEntity synchronizationStateEntity) {
+    Revision revision = new Revision();
+    revision.setRevisionId(synchronizationStateEntity.getRevisionId());
+    revision.setTime(synchronizationStateEntity.getPublishTime());
+    revision.setMessage(synchronizationStateEntity.getMessage());
+    revision.setUser(synchronizationStateEntity.getUser());
+    return revision;
+  }
+
+
+  private Id getLastItemVersionRevision(SessionContext context, Id itemId, Id versionId) {
+
+    ItemVersionRevisions versionRevisions = listItemVersionRevisions(context, itemId, versionId);
+    if(versionRevisions ==null ) return null;
+    return versionRevisions.getItemVersionRevisions().get(0).getRevisionId();
+  }
+
+  protected VersionDao getVersionDao(SessionContext context) {
+    return VersionDaoFactory.getInstance().createInterface(context);
+  }
+
+  protected VersionSynchronizationStateRepository getVersionSyncStateRepository(
+      SessionContext context) {
+    return VersionSynchronizationStateRepositoryFactory.getInstance().createInterface(context);
+  }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/VersionStageStoreImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/VersionStageStoreImpl.java
new file mode 100644
index 0000000..dac9d25
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/collaboration/impl/VersionStageStoreImpl.java
@@ -0,0 +1,39 @@
+package org.openecomp.core.zusammen.plugin.collaboration.impl;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import org.openecomp.core.zusammen.plugin.collaboration.VersionStageStore;
+import org.openecomp.core.zusammen.plugin.dao.VersionStageRepository;
+import org.openecomp.core.zusammen.plugin.dao.VersionStageRepositoryFactory;
+import org.openecomp.core.zusammen.plugin.dao.types.StageEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionContext;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
+
+import java.util.Optional;
+
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.getPrivateSpaceName;
+
+public class VersionStageStoreImpl implements VersionStageStore {
+  @Override
+  public Optional<StageEntity<VersionEntity>> get(SessionContext context, Id itemId,
+                                                  VersionEntity versionEntity) {
+    return getVersionStageRepository(context)
+        .get(context, new VersionContext(getPrivateSpaceName(context), itemId), versionEntity);
+  }
+
+  @Override
+  public void create(SessionContext context, Id itemId, StageEntity<VersionEntity> versionStage) {
+    getVersionStageRepository(context)
+        .create(context, new VersionContext(getPrivateSpaceName(context), itemId), versionStage);
+  }
+
+  @Override
+  public void delete(SessionContext context, Id itemId, VersionEntity version) {
+    getVersionStageRepository(context)
+        .delete(context, new VersionContext(getPrivateSpaceName(context), itemId), version);
+  }
+
+  protected VersionStageRepository getVersionStageRepository(SessionContext context) {
+    return VersionStageRepositoryFactory.getInstance().createInterface(context);
+  }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementRepository.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementRepository.java
index 967814c..7681327 100644
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementRepository.java
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementRepository.java
@@ -1,15 +1,18 @@
 package org.openecomp.core.zusammen.plugin.dao;
 
+import com.amdocs.zusammen.datatypes.Id;
 import com.amdocs.zusammen.datatypes.SessionContext;
 import com.amdocs.zusammen.plugin.statestore.cassandra.dao.types.ElementEntityContext;
 import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
 
-import java.util.Collection;
+import java.util.Map;
 import java.util.Optional;
 
 public interface ElementRepository {
 
-  Collection<ElementEntity> list(SessionContext context, ElementEntityContext elementContext);
+  Map<Id,Id> listIds(SessionContext context, ElementEntityContext elementContext);
+
+/*  void createVersionData(SessionContext context, ElementEntityContext elementContext, VersionDataElement element);*/
 
   void create(SessionContext context, ElementEntityContext elementContext, ElementEntity element);
 
@@ -20,8 +23,28 @@
   Optional<ElementEntity> get(SessionContext context, ElementEntityContext elementContext,
                               ElementEntity element);
 
+  Optional<ElementEntity> getDescriptor(SessionContext context, ElementEntityContext elementContext,
+                                        ElementEntity element);
+
   void createNamespace(SessionContext context, ElementEntityContext elementContext,
                        ElementEntity element);
 
-  boolean checkHealth(SessionContext context);
+  Optional<Id> getHash(SessionContext context, ElementEntityContext elementEntityContext,
+               ElementEntity element);
+
+
+
+
+/*  Collection<SynchronizationStateEntity> listSynchronizationStates(SessionContext context,
+                                              ElementEntityContext elementContext);
+
+  void updateSynchronizationState(SessionContext context, ElementEntityContext elementContext,
+              SynchronizationStateEntity elementSyncState);
+
+  void markAsDirty(SessionContext context, ElementEntityContext elementContext,
+                   SynchronizationStateEntity elementSyncState);
+
+  Optional<SynchronizationStateEntity> getSynchronizationState(SessionContext context,
+                                           ElementEntityContext elementContext,
+                                           SynchronizationStateEntity elementSyncState);*/
 }
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementStageRepository.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementStageRepository.java
new file mode 100644
index 0000000..ac3dc4e
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementStageRepository.java
@@ -0,0 +1,34 @@
+package org.openecomp.core.zusammen.plugin.dao;
+
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.item.Action;
+import com.amdocs.zusammen.plugin.statestore.cassandra.dao.types.ElementEntityContext;
+import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.StageEntity;
+
+import java.util.Collection;
+import java.util.Optional;
+
+public interface ElementStageRepository
+    extends StageRepository<ElementEntityContext, ElementEntity> {
+
+  Optional<StageEntity<ElementEntity>> getDescriptor(SessionContext context,
+                                                     ElementEntityContext elementContext,
+                                                     ElementEntity element);
+
+  Collection<ElementEntity> listIds(SessionContext context,
+                                    ElementEntityContext elementContext);
+
+  Collection<ElementEntity> listConflictedIds(SessionContext context,
+                                              ElementEntityContext elementContext);
+
+  void markAsNotConflicted(SessionContext context, ElementEntityContext entityContext,
+                           ElementEntity entity, Action action);
+
+  void markAsNotConflicted(SessionContext context, ElementEntityContext entityContext,
+                           ElementEntity entity);
+
+  void update(SessionContext context, ElementEntityContext entityContext, ElementEntity entity,
+              Action action, boolean conflicted);
+
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementStageRepositoryFactory.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementStageRepositoryFactory.java
new file mode 100644
index 0000000..1e41308
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementStageRepositoryFactory.java
@@ -0,0 +1,14 @@
+package org.openecomp.core.zusammen.plugin.dao;
+
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.utils.facade.api.AbstractComponentFactory;
+import com.amdocs.zusammen.utils.facade.api.AbstractFactory;
+
+public abstract class ElementStageRepositoryFactory
+    extends AbstractComponentFactory<ElementStageRepository> {
+  public static ElementStageRepositoryFactory getInstance() {
+    return AbstractFactory.getInstance(ElementStageRepositoryFactory.class);
+  }
+
+  public abstract ElementStageRepository createInterface(SessionContext context);
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementSynchronizationStateRepository.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementSynchronizationStateRepository.java
new file mode 100644
index 0000000..53c029b
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementSynchronizationStateRepository.java
@@ -0,0 +1,21 @@
+package org.openecomp.core.zusammen.plugin.dao;
+
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.plugin.statestore.cassandra.dao.types.ElementEntityContext;
+import org.openecomp.core.zusammen.plugin.dao.types.SynchronizationStateEntity;
+
+import java.util.Collection;
+
+public interface ElementSynchronizationStateRepository
+    extends SynchronizationStateRepository<ElementEntityContext> {
+
+  Collection<SynchronizationStateEntity> list(SessionContext context,
+                                              ElementEntityContext elementContext);
+
+  void update(SessionContext context, ElementEntityContext entityContext,
+              SynchronizationStateEntity syncStateEntity);
+
+  void markAsDirty(SessionContext context, ElementEntityContext entityContext,
+                   SynchronizationStateEntity syncStateEntity);
+
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementSynchronizationStateRepositoryFactory.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementSynchronizationStateRepositoryFactory.java
new file mode 100644
index 0000000..26f3bb4
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/ElementSynchronizationStateRepositoryFactory.java
@@ -0,0 +1,14 @@
+package org.openecomp.core.zusammen.plugin.dao;
+
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.utils.facade.api.AbstractComponentFactory;
+import com.amdocs.zusammen.utils.facade.api.AbstractFactory;
+
+public abstract class ElementSynchronizationStateRepositoryFactory
+    extends AbstractComponentFactory<ElementSynchronizationStateRepository> {
+  public static ElementSynchronizationStateRepositoryFactory getInstance() {
+    return AbstractFactory.getInstance(ElementSynchronizationStateRepositoryFactory.class);
+  }
+
+  public abstract ElementSynchronizationStateRepository createInterface(SessionContext context);
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/StageRepository.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/StageRepository.java
new file mode 100644
index 0000000..98b0d82
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/StageRepository.java
@@ -0,0 +1,15 @@
+package org.openecomp.core.zusammen.plugin.dao;
+
+import com.amdocs.zusammen.datatypes.SessionContext;
+import org.openecomp.core.zusammen.plugin.dao.types.StageEntity;
+
+import java.util.Optional;
+
+public interface StageRepository<C, E> {
+
+  Optional<StageEntity<E>> get(SessionContext context, C entityContext, E entity);
+
+  void create(SessionContext context, C entityContext, StageEntity<E> stageEntity);
+
+  void delete(SessionContext context, C entityContext, E entity);
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/SynchronizationStateRepository.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/SynchronizationStateRepository.java
new file mode 100644
index 0000000..f227b0c
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/SynchronizationStateRepository.java
@@ -0,0 +1,16 @@
+package org.openecomp.core.zusammen.plugin.dao;
+
+import com.amdocs.zusammen.datatypes.SessionContext;
+import org.openecomp.core.zusammen.plugin.dao.types.SynchronizationStateEntity;
+
+import java.util.Optional;
+
+public interface SynchronizationStateRepository<C> {
+
+  void create(SessionContext context, C entityContext, SynchronizationStateEntity syncStateEntity);
+
+  void delete(SessionContext context, C entityContext, SynchronizationStateEntity syncStateEntity);
+
+  Optional<SynchronizationStateEntity> get(SessionContext context, C entityContext,
+                                           SynchronizationStateEntity syncStateEntity);
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionDao.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionDao.java
new file mode 100644
index 0000000..f8ad040
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionDao.java
@@ -0,0 +1,29 @@
+package org.openecomp.core.zusammen.plugin.dao;
+
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
+
+import java.util.Collection;
+import java.util.Date;
+import java.util.Map;
+import java.util.Optional;
+
+public interface VersionDao {
+  Collection<VersionEntity> list(SessionContext context, String space, Id itemId);
+
+  Optional<VersionEntity> get(SessionContext context, String space, Id itemId, Id versionId);
+
+  void create(SessionContext context, String space, Id itemId, VersionEntity version);
+
+  void updateModificationTime(SessionContext context, String space, Id itemId, Id versionId, Date modificationTime);
+
+  void delete(SessionContext context, String space, Id itemId, Id versionId);
+
+  boolean checkHealth(SessionContext context);
+
+  void createVersionElements(SessionContext context, String publicSpace, Id itemId, Id versionId,
+                             Id revisionId, Map<Id, Id> versionElementIds, Date publishTime,
+                             String message);
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionDaoFactory.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionDaoFactory.java
new file mode 100644
index 0000000..2847959
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionDaoFactory.java
@@ -0,0 +1,13 @@
+package org.openecomp.core.zusammen.plugin.dao;
+
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.utils.facade.api.AbstractComponentFactory;
+import com.amdocs.zusammen.utils.facade.api.AbstractFactory;
+
+public abstract class VersionDaoFactory extends AbstractComponentFactory<VersionDao> {
+  public static VersionDaoFactory getInstance() {
+    return AbstractFactory.getInstance(VersionDaoFactory.class);
+  }
+
+  public abstract VersionDao createInterface(SessionContext context);
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionStageRepository.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionStageRepository.java
new file mode 100644
index 0000000..568e0c9
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionStageRepository.java
@@ -0,0 +1,9 @@
+package org.openecomp.core.zusammen.plugin.dao;
+
+
+import org.openecomp.core.zusammen.plugin.dao.types.VersionContext;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
+
+public interface VersionStageRepository extends StageRepository<VersionContext, VersionEntity> {
+
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionStageRepositoryFactory.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionStageRepositoryFactory.java
new file mode 100644
index 0000000..fc9e772
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionStageRepositoryFactory.java
@@ -0,0 +1,13 @@
+package org.openecomp.core.zusammen.plugin.dao;
+
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.utils.facade.api.AbstractComponentFactory;
+import com.amdocs.zusammen.utils.facade.api.AbstractFactory;
+
+public abstract class VersionStageRepositoryFactory extends AbstractComponentFactory<VersionStageRepository> {
+  public static VersionStageRepositoryFactory getInstance() {
+    return AbstractFactory.getInstance(VersionStageRepositoryFactory.class);
+  }
+
+  public abstract VersionStageRepository createInterface(SessionContext context);
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionSynchronizationStateRepository.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionSynchronizationStateRepository.java
new file mode 100644
index 0000000..9134392
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionSynchronizationStateRepository.java
@@ -0,0 +1,18 @@
+package org.openecomp.core.zusammen.plugin.dao;
+
+import com.amdocs.zusammen.datatypes.SessionContext;
+import org.openecomp.core.zusammen.plugin.dao.types.SynchronizationStateEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionContext;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
+
+import java.util.List;
+
+public interface VersionSynchronizationStateRepository
+    extends SynchronizationStateRepository<VersionContext> {
+
+  void updatePublishTime(SessionContext context, VersionContext entityContext,
+                         SynchronizationStateEntity syncStateEntity);
+
+  List<SynchronizationStateEntity> list(SessionContext context, VersionContext entityContext,
+                                                  VersionEntity versionEntity);
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionSynchronizationStateRepositoryFactory.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionSynchronizationStateRepositoryFactory.java
new file mode 100644
index 0000000..dfedb58
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/VersionSynchronizationStateRepositoryFactory.java
@@ -0,0 +1,14 @@
+package org.openecomp.core.zusammen.plugin.dao;
+
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.utils.facade.api.AbstractComponentFactory;
+import com.amdocs.zusammen.utils.facade.api.AbstractFactory;
+
+public abstract class VersionSynchronizationStateRepositoryFactory
+    extends AbstractComponentFactory<VersionSynchronizationStateRepository> {
+  public static VersionSynchronizationStateRepositoryFactory getInstance() {
+    return AbstractFactory.getInstance(VersionSynchronizationStateRepositoryFactory.class);
+  }
+
+  public abstract VersionSynchronizationStateRepository createInterface(SessionContext context);
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/CassandraElementRepository.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/CassandraElementRepository.java
deleted file mode 100644
index 6cc1350..0000000
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/CassandraElementRepository.java
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * Copyright © 2016-2017 European Support Limited
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.openecomp.core.zusammen.plugin.dao.impl;
-
-import com.amdocs.zusammen.datatypes.Id;
-import com.amdocs.zusammen.datatypes.Namespace;
-import com.amdocs.zusammen.datatypes.SessionContext;
-import com.amdocs.zusammen.datatypes.item.Info;
-import com.amdocs.zusammen.datatypes.item.Relation;
-import com.amdocs.zusammen.plugin.statestore.cassandra.dao.types.ElementEntityContext;
-import com.amdocs.zusammen.utils.fileutils.json.JsonUtil;
-import com.datastax.driver.core.ResultSet;
-import com.datastax.driver.core.Row;
-import com.datastax.driver.mapping.annotations.Accessor;
-import com.datastax.driver.mapping.annotations.Param;
-import com.datastax.driver.mapping.annotations.Query;
-import com.google.gson.reflect.TypeToken;
-import org.openecomp.core.zusammen.plugin.dao.ElementRepository;
-import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
-
-import java.lang.reflect.Type;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-public class CassandraElementRepository implements ElementRepository {
-
-  private static final String VERSION_ELEMENT_NOT_EXIST_ERROR_MSG =
-      "List version elements error: " +
-          "element %s, which appears as an element of item %s version %s, does not exist";
-
-  @Override
-  public Collection<ElementEntity> list(SessionContext context,
-                                        ElementEntityContext elementContext) {
-    Set<String> elementIds = getVersionElementIds(context, elementContext);
-
-    Collection<ElementEntity> elements = new ArrayList<>();
-    for (String elementId : elementIds) {
-      elements.add(get(context, elementContext, new ElementEntity(new Id(elementId)))
-          .orElseThrow(
-              () -> new IllegalStateException(String.format(VERSION_ELEMENT_NOT_EXIST_ERROR_MSG,
-                  elementId, elementContext.getItemId().getValue(),
-                  getVersionId(elementContext)))));
-    }
-    return elements;
-  }
-
-  @Override
-  public void create(SessionContext context, ElementEntityContext elementContext,
-                     ElementEntity element) {
-    createElement(context, elementContext, element);
-    addElementToParent(context, elementContext, element);
-  }
-
-  @Override
-  public void update(SessionContext context, ElementEntityContext elementContext,
-                     ElementEntity element) {
-    updateElement(context, elementContext, element);
-  }
-
-  @Override
-  public void delete(SessionContext context, ElementEntityContext elementContext,
-                     ElementEntity element) {
-    removeElementFromParent(context, elementContext, element);
-    deleteElement(context, elementContext, element);
-  }
-
-  @Override
-  public Optional<ElementEntity> get(SessionContext context, ElementEntityContext elementContext,
-                                     ElementEntity element) {
-    Row row = getElementAccessor(context).get(
-        elementContext.getSpace(),
-        elementContext.getItemId().toString(),
-        getVersionId(elementContext),
-        element.getId().toString()).one();
-
-    return row == null ? Optional.empty() : Optional.of(getElementEntity(element, row));
-  }
-
-  @Override
-  public void createNamespace(SessionContext context, ElementEntityContext elementContext,
-                              ElementEntity element) {
-    getElementNamespaceAccessor(context).create(
-        elementContext.getSpace(),
-        elementContext.getItemId().toString(),
-        element.getId().toString(),
-        element.getNamespace().toString());
-  }
-
-  @Override
-  public boolean checkHealth(SessionContext context) {
-    ResultSet resultSet = getVersionElementsAccessor(context).checkHealth();
-    return resultSet.getColumnDefinitions().contains("element_ids");
-  }
-
-  private String getVersionId(ElementEntityContext elementContext) {
-    return elementContext.getChangeRef() == null
-        ? elementContext.getVersionId().toString()
-        : elementContext.getChangeRef();
-  }
-
-  private ElementNamespaceAccessor getElementNamespaceAccessor(SessionContext context) {
-    return CassandraDaoUtils.getAccessor(context, ElementNamespaceAccessor.class);
-  }
-
-  private ElementAccessor getElementAccessor(SessionContext context) {
-    return CassandraDaoUtils.getAccessor(context, ElementAccessor.class);
-  }
-
-  private VersionElementsAccessor getVersionElementsAccessor(SessionContext context) {
-    return CassandraDaoUtils.getAccessor(context, VersionElementsAccessor.class);
-  }
-
-  private void createElement(SessionContext context, ElementEntityContext elementContext,
-                             ElementEntity element) {
-    Set<String> subElementIds =
-        element.getSubElementIds().stream().map(Id::toString).collect(Collectors.toSet());
-    String versionId = getVersionId(elementContext);
-
-    getElementAccessor(context).create(
-        elementContext.getSpace(),
-        elementContext.getItemId().toString(),
-        versionId,
-        element.getId().toString(),
-        element.getParentId().toString(),
-        element.getNamespace().toString(),
-        JsonUtil.object2Json(element.getInfo()),
-        JsonUtil.object2Json(element.getRelations()),
-        element.getData(),
-        element.getSearchableData(),
-        element.getVisualization(),
-        subElementIds);
-
-    getVersionElementsAccessor(context).addElements(
-        Collections.singleton(element.getId().toString()),
-        elementContext.getSpace(),
-        elementContext.getItemId().toString(),
-        versionId);
-  }
-
-  private void updateElement(SessionContext context, ElementEntityContext elementContext,
-                             ElementEntity element) {
-    getElementAccessor(context).update(
-        JsonUtil.object2Json(element.getInfo()),
-        JsonUtil.object2Json(element.getRelations()),
-        element.getData(),
-        element.getSearchableData(),
-        element.getVisualization(),
-        elementContext.getSpace(),
-        elementContext.getItemId().toString(),
-        elementContext.getVersionId().toString(),
-        element.getId().toString());
-  }
-
-  private void deleteElement(SessionContext context, ElementEntityContext elementContext,
-                             ElementEntity element) {
-    String versionId = getVersionId(elementContext);
-
-    getElementAccessor(context).delete(
-        elementContext.getSpace(),
-        elementContext.getItemId().toString(),
-        versionId,
-        element.getId().toString());
-
-    getVersionElementsAccessor(context).removeElements(
-        Collections.singleton(element.getId().toString()),
-        elementContext.getSpace(),
-        elementContext.getItemId().toString(),
-        versionId);
-  }
-
-  private void addElementToParent(SessionContext context, ElementEntityContext elementContext,
-                                  ElementEntity element) {
-    getElementAccessor(context).addSubElements(
-        Collections.singleton(element.getId().toString()),
-        elementContext.getSpace(),
-        elementContext.getItemId().toString(),
-        getVersionId(elementContext),
-        element.getParentId().toString());
-  }
-
-  private void removeElementFromParent(SessionContext context, ElementEntityContext elementContext,
-                                       ElementEntity element) {
-    if (element.getParentId() == null) {
-      return;
-    }
-    getElementAccessor(context).removeSubElements(
-        Collections.singleton(element.getId().toString()),
-        elementContext.getSpace(),
-        elementContext.getItemId().toString(),
-        getVersionId(elementContext),
-        element.getParentId().toString());
-  }
-
-  private ElementEntity getElementEntity(ElementEntity element, Row row) {
-    element.setNamespace(getNamespace(row.getString(ElementField.NAMESPACE)));
-    element.setParentId(new Id(row.getString(ElementField.PARENT_ID)));
-    element.setInfo(json2Object(row.getString(ElementField.INFO), Info.class));
-    element.setRelations(
-        json2Object(row.getString(ElementField.RELATIONS), new TypeToken<ArrayList<Relation>>() {
-        }.getType()));
-    element.setData(row.getBytes(ElementField.DATA));
-    element.setSearchableData(row.getBytes(ElementField.SEARCHABLE_DATA));
-    element.setVisualization(row.getBytes(ElementField.VISUALIZATION));
-    element.setSubElementIds(row.getSet(ElementField.SUB_ELEMENT_IDS, String.class)
-        .stream().map(Id::new).collect(Collectors.toSet()));
-    return element;
-  }
-
-  private Namespace getNamespace(String namespaceStr) {
-    Namespace namespace = new Namespace();
-    if (namespaceStr != null) {
-      namespace.setValue(namespaceStr);
-    }
-    return namespace;
-  }
-
-  private static <T> T json2Object(String json, Type typeOfT) {
-    return json == null ? null : JsonUtil.json2Object(json, typeOfT);
-  }
-
-  private Set<String> getVersionElementIds(SessionContext context,
-                                           ElementEntityContext elementContext) {
-    Row row = getVersionElementsAccessor(context).get(
-        elementContext.getSpace(),
-        elementContext.getItemId().toString(),
-        getVersionId(elementContext)).one();
-    return row == null
-        ? new HashSet<>()
-        : row.getSet(CassandraElementRepository.VersionElementsField.ELEMENT_IDS, String.class);
-  }
-
-  /*
-CREATE TABLE IF NOT EXISTS element_namespace (
-	space text,
-	item_id text,
-	element_id text,
-	namespace text,
-	PRIMARY KEY (( space, item_id, element_id ))
-);
-   */
-  @Accessor
-  interface ElementNamespaceAccessor {
-    @Query(
-        "UPDATE element_namespace SET namespace=:ns " +
-            "WHERE space=:space AND item_id=:item AND element_id=:id ")
-    void create(@Param("space") String space,
-                @Param("item") String itemId,
-                @Param("id") String elementId,
-                @Param("ns") String namespace);
-  }
-
-  /*
-CREATE TABLE IF NOT EXISTS element (
-	space text,
-	item_id text,
-	version_id text,
-	element_id text,
-	parent_id text,
-	namespace text,
-	info text,
-	relations text,
-	data blob,
-	searchable_data blob,
-	visualization blob,
-	sub_element_ids set<text>,
-	PRIMARY KEY (( space, item_id, version_id, element_id ))
-);
-   */
-  @Accessor
-  interface ElementAccessor {
-    @Query(
-        "UPDATE element SET parent_id=:parentId, namespace=:ns, info=:info, relations=:rels, " +
-            "data=:data, searchable_data=:searchableData, visualization=:visualization, " +
-            "sub_element_ids=sub_element_ids+:subs " +
-            "WHERE space=:space AND item_id=:item AND version_id=:ver AND element_id=:id ")
-    void create(@Param("space") String space,
-                @Param("item") String itemId,
-                @Param("ver") String versionId,
-                @Param("id") String elementId,
-                @Param("parentId") String parentElementId,
-                @Param("ns") String namespace,
-                @Param("info") String info,
-                @Param("rels") String relations,
-                @Param("data") ByteBuffer data,
-                @Param("searchableData") ByteBuffer searchableData,
-                @Param("visualization") ByteBuffer visualization,
-                @Param("subs") Set<String> subElementIds);
-
-    @Query("UPDATE element SET info=?, relations=?, data=?, searchable_data=?, visualization=?" +
-        " WHERE space=? AND item_id=? AND version_id=? AND element_id=?  ")
-    void update(String info, String relations, ByteBuffer data, ByteBuffer searchableData,
-                ByteBuffer visualization, String space, String itemId, String versionId,
-                String elementId);
-
-    @Query("DELETE FROM element WHERE space=? AND item_id=? AND version_id=? AND element_id=?")
-    void delete(String space, String itemId, String versionId, String elementId);
-
-    @Query("SELECT parent_id, namespace, info, relations, data, searchable_data, visualization, " +
-        "sub_element_ids FROM element " +
-        "WHERE space=? AND item_id=? AND version_id=? AND element_id=? ")
-    ResultSet get(String space, String itemId, String versionId, String elementId);
-
-    @Query("UPDATE element SET sub_element_ids=sub_element_ids+? " +
-        " WHERE space=? AND item_id=? AND version_id=? AND element_id=?  ")
-    void addSubElements(Set<String> subElementIds, String space, String itemId, String versionId,
-                        String elementId);
-
-    @Query("UPDATE element SET sub_element_ids=sub_element_ids-? " +
-        " WHERE space=? AND item_id=? AND version_id=? AND element_id=? ")
-    void removeSubElements(Set<String> subElementIds, String space, String itemId, String versionId,
-                           String elementId);
-  }
-
-  private static final class ElementField {
-    private static final String NAMESPACE = "namespace";
-    private static final String PARENT_ID = "parent_id";
-    private static final String INFO = "info";
-    private static final String RELATIONS = "relations";
-    private static final String DATA = "data";
-    private static final String SEARCHABLE_DATA = "searchable_data";
-    private static final String VISUALIZATION = "visualization";
-    private static final String SUB_ELEMENT_IDS = "sub_element_ids";
-  }
-
-  /*
-  CREATE TABLE IF NOT EXISTS version_elements (
-    space text,
-    item_id text,
-    version_id text,
-    element_ids set<text>,
-    PRIMARY KEY (( space, item_id, version_id ))
-  );
-   */
-  @Accessor
-  interface VersionElementsAccessor {
-
-    @Query("UPDATE version_elements SET element_ids=element_ids+? " +
-        "WHERE space=? AND item_id=? AND version_id=?")
-    void addElements(Set<String> elementIds, String space, String itemId, String versionId);
-
-    @Query("UPDATE version_elements SET element_ids=element_ids-? " +
-        "WHERE space=? AND item_id=? AND version_id=?")
-    void removeElements(Set<String> elementIds, String space, String itemId, String versionId);
-
-    @Query("SELECT element_ids FROM version_elements WHERE space=? AND item_id=? AND version_id=?")
-    ResultSet get(String space, String itemId, String versionId);
-
-    @Query("SELECT element_ids FROM version_elements LIMIT 1")
-    ResultSet checkHealth();
-  }
-
-  private static final class VersionElementsField {
-    private static final String ELEMENT_IDS = "element_ids";
-  }
-}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/CassandraDaoUtils.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/CassandraDaoUtils.java
similarity index 93%
rename from openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/CassandraDaoUtils.java
rename to openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/CassandraDaoUtils.java
index 20a1e18..b6cb9e4 100644
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/CassandraDaoUtils.java
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/CassandraDaoUtils.java
@@ -1,9 +1,9 @@
-package org.openecomp.core.zusammen.plugin.dao.impl;
+package org.openecomp.core.zusammen.plugin.dao.impl.cassandra;
 
-import com.datastax.driver.core.Session;
 import com.amdocs.zusammen.commons.db.api.cassandra.CassandraConnectorFactory;
 import com.amdocs.zusammen.commons.db.api.cassandra.types.CassandraContext;
 import com.amdocs.zusammen.datatypes.SessionContext;
+import com.datastax.driver.core.Session;
 
 class CassandraDaoUtils {
 
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/CassandraElementRepositoryFactory.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementRepositoryFactoryImpl.java
similarity index 80%
rename from openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/CassandraElementRepositoryFactory.java
rename to openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementRepositoryFactoryImpl.java
index f3072a6..8540816 100644
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/CassandraElementRepositoryFactory.java
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementRepositoryFactoryImpl.java
@@ -14,15 +14,15 @@
  * limitations under the License.
  */
 
-package org.openecomp.core.zusammen.plugin.dao.impl;
+package org.openecomp.core.zusammen.plugin.dao.impl.cassandra;
 
 import com.amdocs.zusammen.datatypes.SessionContext;
 import org.openecomp.core.zusammen.plugin.dao.ElementRepository;
 import org.openecomp.core.zusammen.plugin.dao.ElementRepositoryFactory;
 
-public class CassandraElementRepositoryFactory extends ElementRepositoryFactory {
+public class ElementRepositoryFactoryImpl extends ElementRepositoryFactory {
 
-  private static final ElementRepository INSTANCE = new CassandraElementRepository();
+  private static final ElementRepository INSTANCE = new ElementRepositoryImpl();
 
   @Override
   public ElementRepository createInterface(SessionContext context) {
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementRepositoryImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementRepositoryImpl.java
new file mode 100644
index 0000000..bb3b1cf
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementRepositoryImpl.java
@@ -0,0 +1,565 @@
+/*
+ * Copyright © 2016-2017 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.core.zusammen.plugin.dao.impl.cassandra;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.Namespace;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.item.Info;
+import com.amdocs.zusammen.datatypes.item.Relation;
+import com.amdocs.zusammen.plugin.statestore.cassandra.dao.types.ElementEntityContext;
+import com.amdocs.zusammen.utils.fileutils.json.JsonUtil;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.mapping.annotations.Accessor;
+import com.datastax.driver.mapping.annotations.Param;
+import com.datastax.driver.mapping.annotations.Query;
+import com.google.gson.reflect.TypeToken;
+import org.openecomp.core.zusammen.plugin.ZusammenPluginConstants;
+import org.openecomp.core.zusammen.plugin.dao.ElementRepository;
+import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
+
+import java.lang.reflect.Type;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.stream.Collectors;
+
+public class ElementRepositoryImpl implements ElementRepository {
+
+  @Override
+  public Map<Id, Id> listIds(SessionContext context, ElementEntityContext elementContext) {
+
+    if (elementContext.getRevisionId() == null) {
+      String revisionId = calculateLastRevisionId(context, elementContext);
+      if (revisionId == null) {
+        return new HashMap<>();
+      }
+
+      elementContext.setRevisionId(new Id(revisionId));
+    }
+    return getVersionElementIds(context, elementContext).entrySet().stream().collect(Collectors
+        .toMap(entry -> new Id(entry.getKey()), entry -> new Id(entry.getValue())));
+
+   /* return getVersionElementIds(context, elementContext).stream()
+        .map(Id::new)
+        .collect(Collectors.toList());*/
+
+  }
+
+  @Override
+  public void create(SessionContext context, ElementEntityContext elementContext,
+                     ElementEntity element) {
+    createElement(context, elementContext, element);
+    addElementToParent(context, elementContext, element);
+  }
+
+  @Override
+  public void update(SessionContext context, ElementEntityContext elementContext,
+                     ElementEntity element) {
+
+    Id elementRevisionId = getElementRevision(context, elementContext, element.getId());
+    if (elementRevisionId.equals(elementContext.getRevisionId())) {
+      updateElement(context, elementContext, element);
+    } else {
+      createElement(context, elementContext, element);
+    }
+  }
+
+  @Override
+  public void delete(SessionContext context, ElementEntityContext elementContext,
+                     ElementEntity element) {
+    removeElementFromParent(context, elementContext, element);
+    deleteElement(context, elementContext, element);
+  }
+
+  @Override
+  public Optional<ElementEntity> get(SessionContext context, ElementEntityContext elementContext,
+                                     ElementEntity element) {
+    String revisionId = calculateElementRevisionId(context, elementContext, element);
+    if (revisionId == null) {
+      return Optional.empty();
+    }
+
+    Row row = getElementAccessor(context).get(
+        elementContext.getSpace(),
+        elementContext.getItemId().toString(),
+        elementContext.getVersionId().toString(),
+        element.getId().toString(),
+        revisionId).one();
+
+    return row == null ? Optional.empty() : Optional.of(getElementEntity(element, row));
+  }
+
+  @Override
+  public Optional<ElementEntity> getDescriptor(SessionContext context,
+                                               ElementEntityContext elementContext,
+                                               ElementEntity element) {
+    String revisionId = calculateElementRevisionId(context, elementContext, element);
+    if (revisionId == null) {
+      return Optional.empty();
+    }
+
+    Row row = getElementAccessor(context).getDescriptor(
+        elementContext.getSpace(),
+        elementContext.getItemId().toString(),
+        elementContext.getVersionId().toString(),
+        element.getId().toString(),
+        revisionId).one();
+
+    return row == null ? Optional.empty() : Optional.of(getElementEntityDescriptor(element, row));
+  }
+
+  @Override
+  public void createNamespace(SessionContext context, ElementEntityContext elementContext,
+                              ElementEntity element) {
+    getElementNamespaceAccessor(context).create(elementContext.getItemId().toString(),
+        element.getId().toString(),
+        element.getNamespace().toString());
+  }
+
+  @Override
+  public Optional<Id> getHash(SessionContext context, ElementEntityContext elementContext,
+                              ElementEntity element) {
+    String revisionId = calculateElementRevisionId(context, elementContext, element);
+    if (revisionId == null) {
+      return Optional.empty();
+    }
+
+    Row row = getElementAccessor(context).getHash(
+        elementContext.getSpace(),
+        elementContext.getItemId().toString(),
+        elementContext.getVersionId().getValue(),
+        element.getId().toString(),
+        revisionId).one();
+
+    return row == null ? Optional.empty() : Optional.of(getElementHash(row));
+  }
+
+  private String calculateElementRevisionId(SessionContext context,
+                                            ElementEntityContext elementContext,
+                                            ElementEntity element) {
+
+    if (elementContext.getSpace().equals(ZusammenPluginConstants.PUBLIC_SPACE)) {
+
+      String versionRevision;
+      if (elementContext.getRevisionId() == null) {
+        versionRevision = calculateLastRevisionId(context, elementContext);
+      } else {
+        versionRevision = elementContext.getRevisionId().getValue();
+      }
+
+      elementContext.setRevisionId(new Id(versionRevision));
+      Map<String, String> elementIds = getVersionElementIds(context, elementContext);
+      if (elementIds.containsKey(element.getId().getValue())) {
+        return elementIds.get(element.getId().getValue());
+      } else {
+        return null;
+      }
+
+    } else {
+      return Id.ZERO.getValue();
+    }
+  }
+
+  private String calculateLastRevisionId(SessionContext context, ElementEntityContext
+      elementContext) {
+    List<Row> rows = getVersionElementsAccessor(context).listRevisions(elementContext.getSpace(),
+        elementContext
+            .getItemId().toString(), elementContext.getVersionId().toString()).all();
+    if (rows == null || rows.size() == 0) {
+      return null;
+    }
+    rows.sort((o1, o2) -> o1.getDate(VersionElementsField.PUBLISH_TIME)
+        .after(o2.getDate(VersionElementsField.PUBLISH_TIME)) ? -1 : 1);
+    return rows.get(0).getString(VersionElementsField.REVISION_ID);
+  }
+
+  /*private static String getVersionId(ElementEntityContext elementContext) {
+    return elementContext.getRevisionId() == null
+        ? elementContext.getVersionId().toString()
+        : elementContext.getRevisionId().getValue();
+  }*/
+
+  private ElementNamespaceAccessor getElementNamespaceAccessor(SessionContext context) {
+    return CassandraDaoUtils.getAccessor(context, ElementNamespaceAccessor.class);
+  }
+
+  private ElementAccessor getElementAccessor(SessionContext context) {
+    return CassandraDaoUtils.getAccessor(context, ElementAccessor.class);
+  }
+
+  private VersionElementsAccessor getVersionElementsAccessor(SessionContext context) {
+    return CassandraDaoUtils.getAccessor(context, VersionElementsAccessor.class);
+  }
+
+  private void createElement(SessionContext context, ElementEntityContext elementContext,
+                             ElementEntity element) {
+    createElementRow(context, elementContext, element);
+
+    Map<String, String> elementIds = new TreeMap<>();
+    elementIds.put(element.getId().toString(), elementContext.getRevisionId().getValue());
+    getVersionElementsAccessor(context).addElements(
+        elementIds,
+        elementContext.getSpace(),
+        elementContext.getItemId().toString(),
+        elementContext.getVersionId().getValue(),
+        elementContext.getRevisionId().getValue());
+  }
+
+  private void createElementRow(SessionContext context, ElementEntityContext elementContext,
+                                ElementEntity element) {
+    Set<String> subElementIds =
+        element.getSubElementIds().stream().map(Id::toString).collect(Collectors.toSet());
+
+    getElementAccessor(context).create(
+        elementContext.getSpace(),
+        elementContext.getItemId().toString(),
+        elementContext.getVersionId().getValue(),
+        element.getId().toString(),
+        elementContext.getRevisionId().getValue(),
+        element.getParentId() == null ? null : element.getParentId().toString(),
+        element.getNamespace() == null ? null : element.getNamespace().toString(),
+        JsonUtil.object2Json(element.getInfo()),
+        JsonUtil.object2Json(element.getRelations()),
+        element.getData(),
+        element.getSearchableData(),
+        element.getVisualization(),
+        subElementIds,
+        element.getElementHash().getValue());
+  }
+
+  private void updateElement(SessionContext context, ElementEntityContext elementContext,
+                             ElementEntity element) {
+
+
+    if (element.getParentId() == null) {
+      getElementAccessor(context).update(
+          JsonUtil.object2Json(element.getInfo()),
+          JsonUtil.object2Json(element.getRelations()),
+          element.getData(),
+          element.getSearchableData(),
+          element.getVisualization(),
+          element.getElementHash().getValue(),
+          elementContext.getSpace(),
+          elementContext.getItemId().toString(),
+          elementContext.getVersionId().toString(),
+          element.getId().toString(),
+          elementContext.getRevisionId().getValue());
+    } else {
+      getElementAccessor(context).update(
+          JsonUtil.object2Json(element.getInfo()),
+          JsonUtil.object2Json(element.getRelations()),
+          element.getData(),
+          element.getSearchableData(),
+          element.getVisualization(),
+          element.getElementHash().getValue(),
+          element.getParentId().getValue(),
+          elementContext.getSpace(),
+          elementContext.getItemId().toString(),
+          elementContext.getVersionId().toString(),
+          element.getId().getValue(),
+          elementContext.getRevisionId().getValue());
+    }
+
+    Map<String, String> elementIds = new TreeMap<>();
+    elementIds.put(element.getId().getValue(), elementContext.getRevisionId().getValue());
+    getVersionElementsAccessor(context).addElements(
+        elementIds,
+        elementContext.getSpace(),
+        elementContext.getItemId().toString(),
+        elementContext.getVersionId().getValue(),
+        elementContext.getRevisionId().getValue());
+  }
+
+  private void deleteElement(SessionContext context, ElementEntityContext elementContext,
+                             ElementEntity element) {
+
+
+    getElementAccessor(context).delete(
+        elementContext.getSpace(),
+        elementContext.getItemId().toString(),
+        elementContext.getVersionId().toString(),
+        element.getId().toString(),
+        elementContext.getRevisionId().getValue());
+
+    getVersionElementsAccessor(context).removeElements(
+        Collections.singleton(element.getId().toString()),
+        elementContext.getSpace(),
+        elementContext.getItemId().toString(),
+        elementContext.getVersionId().toString(),
+        elementContext.getRevisionId().getValue());
+  }
+
+  private void addElementToParent(SessionContext context, ElementEntityContext elementContext,
+                                  ElementEntity element) {
+    if (element.getParentId() == null) {
+      return;
+    }
+
+
+    getElementAccessor(context).addSubElements(
+        Collections.singleton(element.getId().toString()),
+        elementContext.getSpace(),
+        elementContext.getItemId().toString(),
+        elementContext.getVersionId().toString(),
+        element.getParentId().toString(),
+        elementContext.getRevisionId().getValue());
+
+    Map<String, String> elementIds = new TreeMap<>();
+    elementIds.put(element.getParentId().toString(), elementContext.getRevisionId().getValue());
+    getVersionElementsAccessor(context).addElements(elementIds, elementContext.getSpace(),
+        elementContext.getItemId().getValue(), elementContext.getVersionId().getValue(),
+        elementContext.getRevisionId().getValue());
+  }
+
+  private void removeElementFromParent(SessionContext context, ElementEntityContext elementContext,
+                                       ElementEntity element) {
+
+    if (element.getParentId() == null) {
+      return;
+    }
+
+    Optional<ElementEntity> parentElement =
+        get(context, elementContext, new ElementEntity(element.getParentId()));
+    if (!parentElement.isPresent()) {
+      return;
+    }
+    getElementAccessor(context).removeSubElements(
+        Collections.singleton(element.getId().toString()),
+        elementContext.getSpace(),
+        elementContext.getItemId().toString(),
+        elementContext.getVersionId().toString(),
+        element.getParentId().toString(),
+        elementContext.getRevisionId().getValue());
+
+    getVersionElementsAccessor(context)
+        .removeElements(Collections.singleton(element.getId().toString()),
+            elementContext.getSpace(),
+            elementContext.getItemId().getValue(), elementContext.getVersionId().getValue(),
+            elementContext.getRevisionId().getValue());
+
+    Map<String, String> elementIds = new TreeMap<>();
+    elementIds.put(element.getParentId().toString(), elementContext.getRevisionId().getValue());
+    getVersionElementsAccessor(context).addElements(elementIds, elementContext.getSpace(),
+        elementContext.getItemId().getValue(), elementContext.getVersionId().getValue(),
+        elementContext.getRevisionId().getValue());
+  }
+
+  static ElementEntity getElementEntityDescriptor(ElementEntity element, Row row) {
+    element.setNamespace(getNamespace(row.getString(ElementField.NAMESPACE)));
+    element.setParentId(getParentId(row.getString(ElementField.PARENT_ID)));
+    element.setInfo(json2Object(row.getString(ElementField.INFO), Info.class));
+    element.setRelations(
+        json2Object(row.getString(ElementField.RELATIONS), new TypeToken<ArrayList<Relation>>() {
+        }.getType()));
+
+    element.setSubElementIds(row.getSet(ElementField.SUB_ELEMENT_IDS, String.class)
+        .stream().map(Id::new).collect(Collectors.toSet()));
+    return element;
+  }
+
+  static ElementEntity getElementEntity(ElementEntity element, Row row) {
+    getElementEntityDescriptor(element, row);
+
+    element.setData(row.getBytes(ElementField.DATA));
+    element.setSearchableData(row.getBytes(ElementField.SEARCHABLE_DATA));
+    element.setVisualization(row.getBytes(ElementField.VISUALIZATION));
+    element.setElementHash(new Id(row.getString(ElementField.ELEMENT_HASH)));
+    return element;
+  }
+
+  private Id getElementHash(Row row) {
+    return new Id(row.getString(ElementField.ELEMENT_HASH));
+  }
+
+  private static Id getParentId(String parentIdStr) {
+    return parentIdStr == null ? null : new Id(parentIdStr);
+  }
+
+  private static Namespace getNamespace(String namespaceStr) {
+    Namespace namespace = new Namespace();
+    if (namespaceStr != null) {
+      namespace.setValue(namespaceStr);
+    }
+    return namespace;
+  }
+
+  private static <T> T json2Object(String json, Type typeOfT) {
+    return json == null ? null : JsonUtil.json2Object(json, typeOfT);
+  }
+
+  private Map<String, String> getVersionElementIds(SessionContext context,
+                                                   ElementEntityContext elementContext) {
+    Row row = getVersionElementsAccessor(context).get(
+        elementContext.getSpace(),
+        elementContext.getItemId().toString(),
+        elementContext.getVersionId().getValue(),
+        elementContext.getRevisionId().getValue()).one();
+    return row == null
+        ? new HashMap<>()
+        : row.getMap(ElementRepositoryImpl.VersionElementsField.ELEMENT_IDS, String.class, String
+            .class);
+  }
+
+  private Id getElementRevision(SessionContext context, ElementEntityContext elementContext
+      , Id elementId) {
+    Map<Id, Id> versionElementIds =
+        listIds(context, new ElementEntityContext
+            (elementContext.getSpace(), elementContext.getItemId(), elementContext.getVersionId(),
+                elementContext.getRevisionId()));
+    return versionElementIds.get(elementId);
+
+  }
+
+
+  /*
+CREATE TABLE IF NOT EXISTS element_namespace (
+	item_id text,
+	element_id text,
+	namespace text,
+	PRIMARY KEY (( item_id, element_id ))
+);
+   */
+  @Accessor
+  interface ElementNamespaceAccessor {
+    @Query("UPDATE element_namespace SET namespace=:ns " +
+        "WHERE item_id=:item AND element_id=:id ")
+    void create(@Param("item") String itemId,
+                @Param("id") String elementId,
+                @Param("ns") String namespace);
+  }
+
+  @Accessor
+  interface ElementAccessor {
+    @Query(
+        "UPDATE element SET parent_id=:parentId, namespace=:ns, info=:info, relations=:rels, " +
+            "data=:data, searchable_data=:searchableData, visualization=:visualization, " +
+            "sub_element_ids=sub_element_ids+:subs , element_hash=:elementHash " +
+            " WHERE space=:space AND item_id=:item AND version_id=:ver AND element_id=:id AND " +
+            "revision_id=:rev ")
+    void create(@Param("space") String space,
+                @Param("item") String itemId,
+                @Param("ver") String versionId,
+                @Param("id") String elementId,
+                @Param("rev") String revisionId,
+                @Param("parentId") String parentElementId,
+                @Param("ns") String namespace,
+                @Param("info") String info,
+                @Param("rels") String relations,
+                @Param("data") ByteBuffer data,
+                @Param("searchableData") ByteBuffer searchableData,
+                @Param("visualization") ByteBuffer visualization,
+                @Param("subs") Set<String> subElementIds,
+                @Param("elementHash") String elementHash);
+
+
+    @Query("UPDATE element SET info=?, relations=?, data=?, searchable_data=?, visualization=? ," +
+        "element_hash=? , parent_id=? " +
+        " WHERE space=? AND item_id=? AND version_id=? AND element_id=? AND revision_id=?  ")
+    void update(String info, String relations, ByteBuffer data, ByteBuffer searchableData,
+                ByteBuffer visualization, String elementHash, String parentId, String space, String
+                    itemId, String
+                    versionId, String elementId, String revisionId);
+
+    @Query("UPDATE element SET info=?, relations=?, data=?, searchable_data=?, visualization=? ," +
+        "element_hash=? " +
+        " WHERE space=? AND item_id=? AND version_id=? AND element_id=? AND revision_id=?  ")
+    void update(String info, String relations, ByteBuffer data, ByteBuffer searchableData,
+                ByteBuffer visualization, String elementHash, String space, String
+                    itemId, String
+                    versionId, String elementId, String revisionId);
+
+    @Query(
+        "DELETE FROM element WHERE space=? AND item_id=? AND version_id=? AND element_id=? AND revision_id=? ")
+    void delete(String space, String itemId, String versionId, String elementId, String revisionId);
+
+    @Query("SELECT parent_id, namespace, info, relations, data, searchable_data, visualization, " +
+        "sub_element_ids,element_hash FROM element " +
+        "WHERE space=? AND item_id=? AND version_id=? AND element_id=? AND revision_id=? ")
+    ResultSet get(String space, String itemId, String versionId, String elementId, String
+        revisionId);
+
+    @Query("SELECT parent_id, namespace, info, relations, sub_element_ids FROM element " +
+        "WHERE space=? AND item_id=? AND version_id=? AND element_id=? AND revision_id=? ")
+    ResultSet getDescriptor(String space, String itemId, String versionId, String elementId,
+                            String revisionId);
+
+    @Query("UPDATE element SET sub_element_ids=sub_element_ids+? " +
+        " WHERE space=? AND item_id=? AND version_id=? AND element_id=? AND revision_id=?  ")
+    void addSubElements(Set<String> subElementIds, String space, String itemId, String versionId,
+                        String elementId, String revisionId);
+
+    @Query("UPDATE element SET sub_element_ids=sub_element_ids-? " +
+        " WHERE space=? AND item_id=? AND version_id=? AND element_id=? AND revision_id=? ")
+    void removeSubElements(Set<String> subElementIds, String space, String itemId, String versionId,
+                           String elementId, String revisionId);
+
+    @Query("SELECT element_hash FROM element " +
+        "WHERE space=? AND item_id=? AND version_id=? AND element_id=? AND revision_id=? ")
+    ResultSet getHash(String space, String itemId, String versionId, String elementId, String
+        revisionId);
+  }
+
+  private static final class ElementField {
+    private static final String NAMESPACE = "namespace";
+    private static final String PARENT_ID = "parent_id";
+    private static final String INFO = "info";
+    private static final String RELATIONS = "relations";
+    private static final String DATA = "data";
+    private static final String SEARCHABLE_DATA = "searchable_data";
+    private static final String VISUALIZATION = "visualization";
+    private static final String SUB_ELEMENT_IDS = "sub_element_ids";
+    private static final String ELEMENT_HASH = "element_hash";
+  }
+
+  @Accessor
+  interface VersionElementsAccessor {
+
+    @Query("UPDATE version_elements SET element_ids=element_ids+ ? " +
+        "WHERE space=? AND item_id=? AND version_id=? AND revision_id=? ")
+    void addElements(Map<String, String> elementIds, String space, String itemId, String versionId,
+                     String versionRevisionId);
+
+    @Query("UPDATE version_elements SET element_ids=element_ids-? " +
+        "WHERE space=? AND item_id=? AND version_id=? AND revision_id=?")
+    void removeElements(Set<String> elementIds, String space, String itemId, String versionId,
+                        String revisionId);
+
+    @Query(
+        "SELECT element_ids FROM version_elements WHERE space=? AND item_id=? AND version_id=? AND revision_id=? ")
+    ResultSet get(String space, String itemId, String versionId, String revisionId);
+
+    @Query(
+        "SELECT revision_id,publish_time FROM version_elements WHERE space=? AND item_id=? AND " +
+            "version_id=? ")
+    ResultSet listRevisions(String space, String itemId, String versionId);
+
+  }
+
+  private static final class VersionElementsField {
+    private static final String ELEMENT_IDS = "element_ids";
+    private static final String REVISION_ID = "revision_id";
+    private static final String PUBLISH_TIME = "publish_time";
+  }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/CassandraElementRepositoryFactory.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementStageRepositoryFactoryImpl.java
similarity index 60%
copy from openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/CassandraElementRepositoryFactory.java
copy to openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementStageRepositoryFactoryImpl.java
index f3072a6..02bec12 100644
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/CassandraElementRepositoryFactory.java
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementStageRepositoryFactoryImpl.java
@@ -14,18 +14,18 @@
  * limitations under the License.
  */
 
-package org.openecomp.core.zusammen.plugin.dao.impl;
+package org.openecomp.core.zusammen.plugin.dao.impl.cassandra;
 
 import com.amdocs.zusammen.datatypes.SessionContext;
-import org.openecomp.core.zusammen.plugin.dao.ElementRepository;
-import org.openecomp.core.zusammen.plugin.dao.ElementRepositoryFactory;
+import org.openecomp.core.zusammen.plugin.dao.ElementStageRepository;
+import org.openecomp.core.zusammen.plugin.dao.ElementStageRepositoryFactory;
 
-public class CassandraElementRepositoryFactory extends ElementRepositoryFactory {
+public class ElementStageRepositoryFactoryImpl extends ElementStageRepositoryFactory {
 
-  private static final ElementRepository INSTANCE = new CassandraElementRepository();
+  private static final ElementStageRepository INSTANCE = new ElementStageRepositoryImpl();
 
   @Override
-  public ElementRepository createInterface(SessionContext context) {
+  public ElementStageRepository createInterface(SessionContext context) {
     return INSTANCE;
   }
 }
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementStageRepositoryImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementStageRepositoryImpl.java
new file mode 100644
index 0000000..c215f82
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementStageRepositoryImpl.java
@@ -0,0 +1,423 @@
+/*
+ * Copyright © 2016-2017 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.core.zusammen.plugin.dao.impl.cassandra;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.item.Action;
+import com.amdocs.zusammen.plugin.statestore.cassandra.dao.types.ElementEntityContext;
+import com.amdocs.zusammen.utils.fileutils.json.JsonUtil;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.mapping.annotations.Accessor;
+import com.datastax.driver.mapping.annotations.Param;
+import com.datastax.driver.mapping.annotations.Query;
+import org.openecomp.core.zusammen.plugin.dao.ElementStageRepository;
+import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.StageEntity;
+
+import java.nio.ByteBuffer;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public class ElementStageRepositoryImpl implements ElementStageRepository {
+
+  @Override
+  public Collection<ElementEntity> listIds(SessionContext context,
+                                           ElementEntityContext elementContext) {
+    return getElements(getStageElementIds(context, elementContext));
+  }
+
+  @Override
+  public Collection<ElementEntity> listConflictedIds(SessionContext context,
+                                                     ElementEntityContext elementContext) {
+    return getElements(getConflictedElementIds(context, elementContext));
+  }
+
+  @Override
+  public void create(SessionContext context, ElementEntityContext elementContext,
+                     StageEntity<ElementEntity> elementStage) {
+    createElement(context, elementContext, elementStage);
+    addElementToParent(context, elementContext, elementStage.getEntity());
+  }
+
+  @Override
+  public void markAsNotConflicted(SessionContext context, ElementEntityContext elementContext,
+                                  ElementEntity element, Action action) {
+    getElementStageAccessor(context).updateState(action, false,
+        elementContext.getSpace(),
+        elementContext.getItemId().toString(),
+        elementContext.getVersionId().toString(),
+        element.getId().toString());
+
+    getStageElementsAccessor(context).removeConflictElements(
+        Collections.singleton(element.getId().toString()),
+        elementContext.getSpace(),
+        elementContext.getItemId().toString(),
+        elementContext.getVersionId().toString(),
+        elementContext.getRevisionId().getValue());
+  }
+
+  @Override
+  public void markAsNotConflicted(SessionContext context, ElementEntityContext elementContext,
+                                  ElementEntity element) {
+    getElementStageAccessor(context).markAsNotConflicted(
+        elementContext.getSpace(),
+        elementContext.getItemId().toString(),
+        elementContext.getVersionId().toString(),
+        element.getId().toString());
+
+    getStageElementsAccessor(context).removeConflictElements(
+        Collections.singleton(element.getId().toString()),
+        elementContext.getSpace(),
+        elementContext.getItemId().toString(),
+        elementContext.getVersionId().toString(),
+        elementContext.getRevisionId().getValue());
+  }
+
+  @Override
+  public void update(SessionContext context, ElementEntityContext elementContext,
+                     ElementEntity element, Action action, boolean conflicted) {
+    getElementStageAccessor(context).update(
+        JsonUtil.object2Json(element.getInfo()),
+        JsonUtil.object2Json(element.getRelations()),
+        element.getData(),
+        element.getSearchableData(),
+        element.getVisualization(),
+        element.getElementHash().getValue(),
+        action,
+        conflicted,
+        elementContext.getSpace(),
+        elementContext.getItemId().toString(),
+        elementContext.getVersionId().toString(),
+        element.getId().toString());
+
+    if (!conflicted) {
+      getStageElementsAccessor(context).removeConflictElements(
+          Collections.singleton(element.getId().toString()),
+          elementContext.getSpace(),
+          elementContext.getItemId().toString(),
+          elementContext.getVersionId().toString(),
+          elementContext.getRevisionId().getValue());
+    }
+  }
+
+  @Override
+  public void delete(SessionContext context, ElementEntityContext elementContext,
+                     ElementEntity element) {
+    removeElementFromParent(context, elementContext, element);
+    deleteElement(context, elementContext, element);
+  }
+
+  @Override
+  public Optional<StageEntity<ElementEntity>> get(SessionContext context,
+                                                  ElementEntityContext elementContext,
+                                                  ElementEntity element) {
+    Row row = getElementStageAccessor(context).get(
+        elementContext.getSpace(),
+        elementContext.getItemId().toString(),
+        elementContext.getVersionId().getValue(),
+        element.getId().toString()).one();
+
+    return row == null ? Optional.empty() : Optional.of(getStageElement(row));
+  }
+
+  @Override
+  public Optional<StageEntity<ElementEntity>> getDescriptor(SessionContext context,
+                                                            ElementEntityContext elementContext,
+                                                            ElementEntity element) {
+    Row row = getElementStageAccessor(context).getDescriptor(
+        elementContext.getSpace(),
+        elementContext.getItemId().toString(),
+        elementContext.getVersionId().getValue(),
+        element.getId().toString()).one();
+
+    return row == null ? Optional.empty() : Optional.of(getStageElementDescriptor(row));
+  }
+
+
+
+  private Collection<ElementEntity> getElements(Set<String> elementIds) {
+    return elementIds.stream()
+        .map(id -> new ElementEntity(new Id(id)))
+        .collect(Collectors.toList());
+  }
+
+  private void createElement(SessionContext context, ElementEntityContext elementContext,
+                             StageEntity<ElementEntity> elementStage) {
+
+
+    ElementEntity element = elementStage.getEntity();
+    Set<String> subElementIds =
+        element.getSubElementIds().stream().map(Id::toString).collect(Collectors.toSet());
+    Set<String> conflictDependents = elementStage.getConflictDependents().stream()
+        .map(conflictDependent -> conflictDependent.getId().getValue())
+        .collect(Collectors.toSet());
+
+    getElementStageAccessor(context).create(
+        elementContext.getSpace(),
+        elementContext.getItemId().toString(),
+        elementContext.getVersionId().getValue(),
+        element.getId().toString(),
+        element.getParentId() == null ? null : element.getParentId().toString(),
+        element.getNamespace() == null ? null : element.getNamespace().toString(),
+        JsonUtil.object2Json(element.getInfo()),
+        JsonUtil.object2Json(element.getRelations()),
+        element.getData(),
+        element.getSearchableData(),
+        element.getVisualization(),
+        subElementIds,
+        element.getElementHash() == null ? null : element.getElementHash().getValue(),
+        elementStage.getPublishTime(),
+        elementStage.getAction(),
+        elementStage.isConflicted(),
+        conflictDependents);
+
+    getStageElementsAccessor(context).add(
+        Collections.singleton(element.getId().toString()),
+        elementContext.getSpace(),
+        elementContext.getItemId().toString(),
+        elementContext.getVersionId().getValue(),
+        elementContext.getRevisionId().getValue());
+
+    if (elementStage.isConflicted()) {
+      getStageElementsAccessor(context).addConflictElements(
+          Collections.singleton(element.getId().toString()),
+          elementContext.getSpace(),
+          elementContext.getItemId().toString(),
+          elementContext.getVersionId().getValue(),
+          elementContext.getRevisionId().getValue());
+    }
+  }
+
+  private void deleteElement(SessionContext context, ElementEntityContext elementContext,
+                             ElementEntity element) {
+
+
+    getElementStageAccessor(context).delete(
+        elementContext.getSpace(),
+        elementContext.getItemId().toString(),
+        elementContext.getVersionId().getValue(),
+        element.getId().toString());
+
+    getStageElementsAccessor(context).remove(
+        Collections.singleton(element.getId().toString()),
+        elementContext.getSpace(),
+        elementContext.getItemId().toString(),
+        elementContext.getVersionId().getValue(),
+        elementContext.getRevisionId().getValue());
+  }
+
+  private void addElementToParent(SessionContext context, ElementEntityContext elementContext,
+                                  ElementEntity element) {
+    if (element.getParentId() == null) {
+      return;
+    }
+    getElementStageAccessor(context).addSubElements(
+        Collections.singleton(element.getId().toString()),
+        elementContext.getSpace(),
+        elementContext.getItemId().toString(),
+        elementContext.getVersionId().getValue(),
+        element.getParentId().toString());
+  }
+
+  private void removeElementFromParent(SessionContext context, ElementEntityContext elementContext,
+                                       ElementEntity element) {
+    if (element.getParentId() == null) {
+      return;
+    }
+    getElementStageAccessor(context).removeSubElements(
+        Collections.singleton(element.getId().toString()),
+        elementContext.getSpace(),
+        elementContext.getItemId().toString(),
+        elementContext.getVersionId().getValue(),
+        element.getParentId().toString());
+  }
+
+  private StageEntity<ElementEntity> getStageElementDescriptor(Row row) {
+    return buildStageElement(ElementRepositoryImpl.getElementEntityDescriptor(
+        new ElementEntity(new Id(row.getString(ElementStageField.ID))), row), row);
+  }
+
+  private StageEntity<ElementEntity> getStageElement(Row row) {
+    return buildStageElement(ElementRepositoryImpl.getElementEntity(
+        new ElementEntity(new Id(row.getString(ElementStageField.ID))), row), row);
+  }
+
+
+  private StageEntity<ElementEntity> buildStageElement(ElementEntity element, Row row) {
+    StageEntity<ElementEntity> elementStage =
+        new StageEntity<>(element, row.getDate(ElementStageField.PUBLISH_TIME));
+    elementStage.setAction(Action.valueOf(row.getString(ElementStageField.ACTION)));
+    elementStage.setConflicted(row.getBool(ElementStageField.CONFLICTED));
+    elementStage.setConflictDependents(
+        row.getSet(ElementStageField.CONFLICT_DEPENDENTS, String.class).stream()
+            .map(conflictDependentId -> new ElementEntity(new Id(conflictDependentId)))
+            .collect(Collectors.toSet()));
+    return elementStage;
+  }
+
+  private Set<String> getStageElementIds(SessionContext context,
+                                         ElementEntityContext elementContext) {
+    Row row = getStageElementsAccessor(context).get(
+        elementContext.getSpace(),
+        elementContext.getItemId().toString(),
+        elementContext.getVersionId().getValue(),
+        elementContext.getRevisionId().getValue()).one();
+    return row == null ? new HashSet<>()
+        : row.getSet(StageElementsField.STAGE_ELEMENT_IDS, String.class);
+  }
+
+  private Set<String> getConflictedElementIds(SessionContext context,
+                                              ElementEntityContext elementContext) {
+    Row row = getStageElementsAccessor(context).getConflicted(
+        elementContext.getSpace(),
+        elementContext.getItemId().toString(),
+        elementContext.getVersionId().getValue(),
+        elementContext.getRevisionId().getValue()).one();
+    return row == null ? new HashSet<>()
+        : row.getSet(StageElementsField.CONFLICT_ELEMENT_IDS, String.class);
+  }
+
+  private ElementStageAccessor getElementStageAccessor(SessionContext context) {
+    return CassandraDaoUtils.getAccessor(context, ElementStageAccessor.class);
+  }
+
+  private StageElementsAccessor getStageElementsAccessor(SessionContext context) {
+    return CassandraDaoUtils.getAccessor(context, StageElementsAccessor.class);
+  }
+
+  @Accessor
+  interface ElementStageAccessor {
+    @Query(
+        "UPDATE element_stage SET parent_id=:parentId, namespace=:ns, info=:info, relations=:rels, " +
+            "data=:data, searchable_data=:searchableData, visualization=:visualization, " +
+            "publish_time=:publishTime, action=:action, " +
+            "conflicted=:conflicted, conflict_dependent_ids=:conflictDependents, " +
+            "sub_element_ids=sub_element_ids+:subs, element_hash=:elementHash " +
+            "WHERE space=:space AND item_id=:item AND version_id=:ver AND element_id=:id ")
+    void create(@Param("space") String space,
+                @Param("item") String itemId,
+                @Param("ver") String versionId,
+                @Param("id") String elementId,
+                @Param("parentId") String parentElementId,
+                @Param("ns") String namespace,
+                @Param("info") String info,
+                @Param("rels") String relations,
+                @Param("data") ByteBuffer data,
+                @Param("searchableData") ByteBuffer searchableData,
+                @Param("visualization") ByteBuffer visualization,
+                @Param("subs") Set<String> subElementIds,
+                @Param("elementHash") String elementHash,
+                @Param("publishTime") Date publishTime,
+                @Param("action") Action action,
+                @Param("conflicted") boolean conflicted,
+                @Param("conflictDependents") Set<String> conflictDependents);
+
+    @Query("UPDATE element_stage SET info=?, relations=?, data=?, searchable_data=?, " +
+        "visualization=?,element_hash=?, action=?, conflicted=? " +
+        " WHERE space=? AND item_id=? AND version_id=? AND element_id=?  ")
+    void update(String info, String relations, ByteBuffer data, ByteBuffer searchableData,
+                ByteBuffer visualization, String elementHash, Action action, boolean conflicted,
+                String space,
+                String itemId, String versionId, String elementId);
+
+    @Query("UPDATE element_stage SET action=?, conflicted=? " +
+        " WHERE space=? AND item_id=? AND version_id=? AND element_id=?  ")
+    void updateState(Action action, boolean conflicted, String space, String itemId,
+                     String versionId, String elementId);
+
+    @Query("UPDATE element_stage SET conflicted=false " +
+        " WHERE space=? AND item_id=? AND version_id=? AND element_id=?  ")
+    void markAsNotConflicted(String space, String itemId, String versionId, String elementId);
+
+    @Query(
+        "DELETE FROM element_stage WHERE space=? AND item_id=? AND version_id=? AND element_id=?")
+    void delete(String space, String itemId, String versionId, String elementId);
+
+    @Query("SELECT element_id, parent_id, namespace, info, relations, data, searchable_data, " +
+        "visualization, sub_element_ids,element_hash, publish_time, action, " +
+        "conflicted, conflict_dependent_ids FROM element_stage " +
+        "WHERE space=? AND item_id=? AND version_id=? AND element_id=? ")
+    ResultSet get(String space, String itemId, String versionId, String elementId);
+
+    @Query("SELECT element_id, parent_id, namespace, info, relations, " +
+        "sub_element_ids, publish_time, action, conflicted, conflict_dependent_ids " +
+        "FROM element_stage WHERE space=? AND item_id=? AND version_id=? AND element_id=? ")
+    ResultSet getDescriptor(String space, String itemId, String versionId, String elementId);
+
+    @Query("UPDATE element_stage SET sub_element_ids=sub_element_ids+? " +
+        " WHERE space=? AND item_id=? AND version_id=? AND element_id=?  ")
+    void addSubElements(Set<String> subElementIds, String space, String itemId, String versionId,
+                        String elementId);
+
+    @Query("UPDATE element_stage SET sub_element_ids=sub_element_ids-? " +
+        " WHERE space=? AND item_id=? AND version_id=? AND element_id=? ")
+    void removeSubElements(Set<String> subElementIds, String space, String itemId, String versionId,
+                           String elementId);
+  }
+
+  private static final class ElementStageField {
+    private static final String ID = "element_id";
+    private static final String PUBLISH_TIME = "publish_time";
+    private static final String ACTION = "action";
+    private static final String CONFLICTED = "conflicted";
+    private static final String CONFLICT_DEPENDENTS = "conflict_dependent_ids";
+  }
+
+  @Accessor
+  interface StageElementsAccessor {
+
+    @Query("UPDATE version_elements SET stage_element_ids=stage_element_ids+? " +
+        "WHERE space=? AND item_id=? AND version_id=? AND revision_id=? ")
+    void add(Set<String> elementIds, String space, String itemId, String versionId, String
+        revisionId);
+
+    @Query("UPDATE version_elements SET stage_element_ids=stage_element_ids-? " +
+        "WHERE space=? AND item_id=? AND version_id=? AND revision_id=? ")
+    void remove(Set<String> elementIds, String space, String itemId, String versionId, String
+        revisionId);
+
+    @Query("SELECT stage_element_ids FROM version_elements " +
+        "WHERE space=? AND item_id=? AND version_id=? AND revision_id=?")
+    ResultSet get(String space, String itemId, String versionId, String revisionId);
+
+    @Query("UPDATE version_elements SET conflict_element_ids=conflict_element_ids+? " +
+        "WHERE space=? AND item_id=? AND version_id=? AND revision_id=? ")
+    void addConflictElements(Set<String> elementIds, String space, String itemId, String
+        versionId, String revisionId);
+
+    @Query("UPDATE version_elements SET conflict_element_ids=conflict_element_ids-? " +
+        "WHERE space=? AND item_id=? AND version_id=? AND revision_id=? ")
+    void removeConflictElements(Set<String> elementIds, String space, String itemId,
+                                String versionId, String revisionId);
+
+    @Query("SELECT conflict_element_ids FROM version_elements " +
+        "WHERE space=? AND item_id=? AND version_id=? AND revision_id=? ")
+    ResultSet getConflicted(String space, String itemId, String versionId, String revisionId);
+  }
+
+  private static final class StageElementsField {
+    private static final String STAGE_ELEMENT_IDS = "stage_element_ids";
+    private static final String CONFLICT_ELEMENT_IDS = "conflict_element_ids";
+  }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementSynchronizationStateRepositoryFactoryImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementSynchronizationStateRepositoryFactoryImpl.java
new file mode 100644
index 0000000..ec7e1c3
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementSynchronizationStateRepositoryFactoryImpl.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright © 2016-2017 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.core.zusammen.plugin.dao.impl.cassandra;
+
+import com.amdocs.zusammen.datatypes.SessionContext;
+import org.openecomp.core.zusammen.plugin.dao.ElementSynchronizationStateRepository;
+import org.openecomp.core.zusammen.plugin.dao.ElementSynchronizationStateRepositoryFactory;
+
+public class ElementSynchronizationStateRepositoryFactoryImpl
+    extends ElementSynchronizationStateRepositoryFactory {
+
+  private static final ElementSynchronizationStateRepository INSTANCE =
+      new ElementSynchronizationStateRepositoryImpl();
+
+  @Override
+  public ElementSynchronizationStateRepository createInterface(SessionContext context) {
+    return INSTANCE;
+  }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementSynchronizationStateRepositoryImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementSynchronizationStateRepositoryImpl.java
new file mode 100644
index 0000000..d41d3d7
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/ElementSynchronizationStateRepositoryImpl.java
@@ -0,0 +1,209 @@
+package org.openecomp.core.zusammen.plugin.dao.impl.cassandra;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.plugin.statestore.cassandra.dao.types.ElementEntityContext;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.mapping.annotations.Accessor;
+import com.datastax.driver.mapping.annotations.Query;
+import org.openecomp.core.zusammen.plugin.dao.ElementSynchronizationStateRepository;
+import org.openecomp.core.zusammen.plugin.dao.types.SynchronizationStateEntity;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public class ElementSynchronizationStateRepositoryImpl
+    implements ElementSynchronizationStateRepository {
+
+  @Override
+  public Collection<SynchronizationStateEntity> list(SessionContext context,
+                                                     ElementEntityContext elementContext) {
+    List<Row> rows = getAccessor(context)
+        .list(elementContext.getSpace(),
+            elementContext.getItemId().toString(),
+            elementContext.getVersionId().toString()).all();
+    return rows == null ? new HashSet<>()
+        : rows.stream().map(this::getSynchronizationStateEntity).collect(Collectors.toSet());
+
+  }
+
+  @Override
+  public void create(SessionContext context, ElementEntityContext elementContext,
+                     SynchronizationStateEntity elementSyncState) {
+    update(context, elementContext.getSpace(),
+        elementContext.getItemId(),
+        elementContext.getVersionId(),
+        elementContext.getRevisionId(),
+        elementSyncState.getRevisionId(),
+        elementSyncState.getId(),
+        elementSyncState.getPublishTime(),
+        elementSyncState.isDirty()
+
+    );
+  }
+
+  @Override
+  public void update(SessionContext context, ElementEntityContext elementContext,
+                     SynchronizationStateEntity elementSyncState) {
+    update(context, elementContext.getSpace(),
+        elementContext.getItemId(),
+        elementContext.getVersionId(),
+        elementContext.getRevisionId(),
+        elementSyncState.getRevisionId(),
+        elementSyncState.getId(),
+        elementSyncState.getPublishTime(),
+        elementSyncState.isDirty()
+
+    );
+  }
+
+  @Override
+  public void markAsDirty(SessionContext context, ElementEntityContext elementContext,
+                          SynchronizationStateEntity elementSyncState) {
+
+
+      getAccessor(context).updateDirty(true,
+          elementContext.getSpace(),
+          elementContext.getItemId().toString(),
+          elementContext.getVersionId().toString(),
+          elementSyncState.getId().toString(),
+          elementContext.getRevisionId().getValue());
+
+      getVersionElementsAccessor(context).addDirtyElements(
+          Collections.singleton(elementSyncState.getId().toString()), elementContext.getSpace(),
+          elementContext.getItemId().toString(),
+          elementContext.getVersionId().toString(),
+          elementContext.getRevisionId().getValue());
+  }
+
+  @Override
+  public void delete(SessionContext context, ElementEntityContext elementContext,
+                     SynchronizationStateEntity elementSyncState) {
+    getAccessor(context).delete(elementContext.getSpace(),
+        elementContext.getItemId().toString(),
+        elementContext.getVersionId().toString(),
+        elementSyncState.getId().toString(),
+        elementContext.getRevisionId().getValue());
+
+    getVersionElementsAccessor(context).removeDirtyElements(
+        Collections.singleton(elementSyncState.getId().toString()), elementContext.getSpace(),
+        elementContext.getItemId().toString(),
+        elementContext.getVersionId().toString(),
+        elementContext.getRevisionId().getValue());
+  }
+
+  @Override
+  public Optional<SynchronizationStateEntity> get(SessionContext context,
+                                                  ElementEntityContext elementContext,
+                                                  SynchronizationStateEntity elementSyncState) {
+
+    Row row = getAccessor(context)
+        .get(elementContext.getSpace(),
+            elementContext.getItemId().toString(),
+            elementContext.getVersionId().toString(),
+            elementSyncState.getId().toString(),
+            elementSyncState.getRevisionId().getValue()).one();
+
+    return row == null ? Optional.empty() : Optional.of(getSynchronizationStateEntity(row));
+  }
+
+  private void update(SessionContext context, String space, Id itemId, Id versionId, Id
+      versionRevisionId,Id elementRevisionId,Id elementId, Date publishTime, boolean isDirty) {
+    getAccessor(context).update(publishTime,
+        isDirty,
+        space,
+        itemId.toString(),
+        versionId.toString(),
+        elementId.toString(),
+        elementRevisionId.getValue());
+
+    if (isDirty) {
+      getVersionElementsAccessor(context).addDirtyElements(
+          Collections.singleton(elementId.toString()), space,
+          itemId.toString(),
+          versionId.toString(),
+          versionRevisionId.getValue());
+    } else {
+      getVersionElementsAccessor(context).removeDirtyElements(
+          Collections.singleton(elementId.toString()), space,
+          itemId.toString(),
+          versionId.toString(),
+          versionRevisionId.getValue());
+    }
+  }
+
+
+  private SynchronizationStateEntity getSynchronizationStateEntity(Row row) {
+    SynchronizationStateEntity entity =
+        new SynchronizationStateEntity(new Id(row.getString(SynchronizationStateField.ID)),
+            new Id(row.getString(SynchronizationStateField.REVISION_ID)),
+            row.getDate(SynchronizationStateField.PUBLISH_TIME),
+            row.getBool(SynchronizationStateField.DIRTY));
+    entity.setRevisionId(new Id(row.getString(SynchronizationStateField.REVISION_ID)));
+
+    return entity;
+
+  }
+
+  private ElementSynchronizationStateAccessor getAccessor(SessionContext context) {
+    return CassandraDaoUtils.getAccessor(context, ElementSynchronizationStateAccessor.class);
+  }
+
+  private VersionElementsAccessor getVersionElementsAccessor(SessionContext context) {
+    return CassandraDaoUtils.getAccessor(context, VersionElementsAccessor.class);
+  }
+
+  @Accessor
+  interface ElementSynchronizationStateAccessor {
+    @Query("UPDATE element_synchronization_state SET publish_time=?, dirty=? " +
+        "WHERE space=? AND item_id=? AND version_id=? AND element_id=? AND revision_id = ? ")
+    void update(Date publishTime, boolean dirty, String space, String itemId, String versionId,
+                String elementId, String revisionId);
+
+    @Query("UPDATE element_synchronization_state SET dirty=? " +
+        "WHERE space=? AND item_id=? AND version_id=? AND element_id=? AND revision_id = ? ")
+    void updateDirty(boolean dirty, String space, String itemId, String versionId,
+                     String elementId, String revisionId);
+
+    @Query("DELETE FROM element_synchronization_state " +
+        "WHERE space=? AND item_id=? AND version_id=? AND element_id=? AND revision_id = ? ")
+    void delete(String space, String itemId, String versionId, String elementId, String revisionId);
+
+    @Query("SELECT element_id,revision_id, publish_time, dirty FROM element_synchronization_state" +
+        " WHERE space=? AND item_id=? AND version_id=?")
+    ResultSet list(String space, String itemId, String versionId);
+
+    @Query("SELECT element_id,revision_id, publish_time, dirty FROM element_synchronization_state" +
+        " WHERE space=? AND item_id=? AND version_id=? AND element_id=? AND revision_id = ?  ")
+    ResultSet get(String space, String itemId, String versionId, String elementId, String
+        revisionId);
+  }
+
+  private static final class SynchronizationStateField {
+    private static final String ID = "element_id";
+    private static final String PUBLISH_TIME = "publish_time";
+    private static final String DIRTY = "dirty";
+    private static final String REVISION_ID = "revision_id";
+  }
+
+  @Accessor
+  interface VersionElementsAccessor {
+
+    @Query("UPDATE version_elements SET dirty_element_ids=dirty_element_ids+? " +
+        "WHERE space=? AND item_id=? AND version_id=? AND revision_id=?")
+    void addDirtyElements(Set<String> elementIds, String space, String itemId, String versionId,
+                          String revisionId);
+
+    @Query("UPDATE version_elements SET dirty_element_ids=dirty_element_ids-? " +
+        "WHERE space=? AND item_id=? AND version_id=? AND revision_id=? ")
+    void removeDirtyElements(Set<String> elementIds, String space, String itemId, String
+        versionId, String revisionId);
+  }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionDaoFactoryImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionDaoFactoryImpl.java
new file mode 100644
index 0000000..60dc9d17
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionDaoFactoryImpl.java
@@ -0,0 +1,15 @@
+package org.openecomp.core.zusammen.plugin.dao.impl.cassandra;
+
+import com.amdocs.zusammen.datatypes.SessionContext;
+import org.openecomp.core.zusammen.plugin.dao.VersionDao;
+import org.openecomp.core.zusammen.plugin.dao.VersionDaoFactory;
+
+public class VersionDaoFactoryImpl extends VersionDaoFactory {
+
+  private static final VersionDao INSTANCE = new VersionDaoImpl();
+
+  @Override
+  public VersionDao createInterface(SessionContext context) {
+    return INSTANCE;
+  }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionDaoImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionDaoImpl.java
new file mode 100644
index 0000000..bba2ddf
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionDaoImpl.java
@@ -0,0 +1,185 @@
+package org.openecomp.core.zusammen.plugin.dao.impl.cassandra;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.mapping.annotations.Accessor;
+import com.datastax.driver.mapping.annotations.Query;
+import org.openecomp.core.zusammen.plugin.dao.VersionDao;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import static java.util.stream.Collectors.toMap;
+
+public class VersionDaoImpl implements VersionDao {
+
+  @Override
+  public void create(SessionContext context, String space, Id itemId, VersionEntity version) {
+    String baseVersion = version.getBaseId() != null ? version.getBaseId().toString() : null;
+
+    getAccessor(context)
+        .create(space, itemId.toString(), version.getId().toString(),
+            baseVersion,
+            version.getCreationTime(), version.getModificationTime());
+
+  }
+
+  @Override
+  public void delete(SessionContext context, String space, Id itemId, Id versionId) {
+
+    getAccessor(context).delete(space, itemId.toString(), versionId.toString());
+  }
+
+  @Override
+  public void updateModificationTime(SessionContext context, String space, Id itemId,
+                                     Id versionId, Date modificationTime) {
+    getAccessor(context)
+        .updateModificationTime(modificationTime, space, itemId.toString(), versionId.toString());
+  }
+
+
+  @Override
+  public Collection<VersionEntity> list(SessionContext context, String space, Id itemId) {
+    List<Row> rows = getAccessor(context).list(space, itemId.toString()).all();
+    return rows == null ? new ArrayList<>() :
+        rows.stream().map(VersionDaoImpl::convertToVersionEntity).collect(Collectors.toList());
+  }
+
+
+  @Override
+  public Optional<VersionEntity> get(SessionContext context, String space, Id itemId,
+                                     Id versionId) {
+    Row row;
+
+    row = getAccessor(context).get(space, itemId.toString(), versionId.toString()).one();
+
+
+    return row == null ? Optional.empty() : Optional.of(convertToVersionEntity(row));
+  }
+
+  @Override
+  public boolean checkHealth(SessionContext context) {
+    return getAccessor(context).checkHealth().getColumnDefinitions()
+        .contains(VersionField.VERSION_ID);
+  }
+
+  @Override
+  public void createVersionElements(SessionContext context, String space, Id itemId,
+                                    Id versionId, Id revisionId, Map<Id, Id> versionElementIds,
+                                    Date publishTime, String message) {
+    Map<String, String> elementIds = versionElementIds==null?null:versionElementIds.
+        entrySet().
+        stream().
+        collect(toMap((Map.Entry<Id, Id>entry)->entry.getKey().getValue(),
+                      (Map.Entry<Id, Id>entry)->entry.getValue().getValue()));
+
+    getVersionElementsAccessor(context).create(space,itemId.toString(),versionId.toString(),
+        revisionId.getValue(),elementIds,publishTime,message,context.getUser().getUserName());
+  }
+
+
+  private static VersionEntity convertToVersionEntity(Row row) {
+
+    /*Id revisionId =  row.getColumnDefinitions().contains("revision_id")?new Id(row.getString
+        (VersionField.REVISION_ID)):null;*/
+
+    VersionEntity version = new VersionEntity(new Id(row.getString(VersionField.VERSION_ID)));
+    return enrichVersionEntity(version, row);
+  }
+
+  static VersionEntity enrichVersionEntity(VersionEntity version, Row row) {
+    version.setBaseId(new Id(row.getString(VersionField.BASE_VERSION_ID)));
+    version.setCreationTime(row.getDate(VersionField.CREATION_TIME));
+    version.setModificationTime(row.getDate(VersionField.MODIFICATION_TIME));
+    return version;
+  }
+
+  private VersionAccessor getAccessor(SessionContext context) {
+    return CassandraDaoUtils.getAccessor(context, VersionAccessor.class);
+  }
+
+  private VersionElementsAccessor getVersionElementsAccessor(SessionContext context) {
+    return CassandraDaoUtils.getAccessor(context, VersionElementsAccessor.class);
+  }
+
+  @Accessor
+  interface VersionAccessor {
+
+    @Query(
+        "INSERT INTO version (space, item_id, version_id, base_version_id, " +
+            "creation_time, " +
+            "modification_time) " +
+            "VALUES (?, ?, ?, ?, ?, ?)")
+    void create(String space, String itemId, String versionId, String baseVersionId,
+                Date creationTime, Date modificationTime);
+
+    @Query("UPDATE version SET modification_time=? WHERE space=? AND item_id=? AND version_id=? ")
+    void updateModificationTime(Date modificationTime, String space, String itemId,
+                                String versionId);
+
+    @Query("DELETE FROM version WHERE space=? AND item_id=? AND version_id=? ")
+    void delete(String space, String itemId, String versionId);
+
+    @Query("SELECT version_id, base_version_id, creation_time, modification_time " +
+        "FROM version WHERE space=? AND item_id=? AND version_id=?  ")
+    ResultSet get(String space, String itemId, String versionId);
+
+    /*@Query("SELECT version_id, base_version_id, creation_time, modification_time " +
+        "FROM version WHERE space=? AND item_id=? AND version_id=? ")
+    ResultSet get(String space, String itemId, String versionId);*/
+
+
+    @Query("SELECT version_id, base_version_id, creation_time, modification_time " +
+        "FROM version WHERE space=? AND item_id=?")
+    ResultSet list(String space, String itemId);
+
+    @Query("SELECT version_id FROM version LIMIT 1")
+    ResultSet checkHealth();
+  }
+
+  private static final class VersionField {
+    private static final String VERSION_ID = "version_id";
+    private static final String BASE_VERSION_ID = "base_version_id";
+    private static final String CREATION_TIME = "creation_time";
+    private static final String MODIFICATION_TIME = "modification_time";
+    //private static final String REVISION_ID = "revision_id";
+  }
+
+  @Accessor
+  interface VersionElementsAccessor {
+
+    @Query("INSERT INTO version_elements (space,item_id,version_id,revision_id,element_ids," +
+        "publish_time,message,user) " +
+        "VALUES (?,?,?,?,?,?,?,?)")
+    void create(String space,
+                String itemId,
+                String versionId,
+                String versionRevisionId,
+                Map<String,String> elementIds,
+                Date publishTime,
+                String message,
+                String user);
+
+
+
+  }
+
+ /* public static final class VersionElementsField {
+    private static final String SPACE = "space";
+    private static final String ITEM_ID = "item_id";
+    private static final String VERSION_ID = "version_id";
+    private static final String ELEMENT_IDS = "element_ids";
+    private static final String REVISION_ID = "revision_id";
+
+  }*/
+
+
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionStageRepositoryFactoryImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionStageRepositoryFactoryImpl.java
new file mode 100644
index 0000000..547bf6a
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionStageRepositoryFactoryImpl.java
@@ -0,0 +1,15 @@
+package org.openecomp.core.zusammen.plugin.dao.impl.cassandra;
+
+import com.amdocs.zusammen.datatypes.SessionContext;
+import org.openecomp.core.zusammen.plugin.dao.VersionStageRepository;
+import org.openecomp.core.zusammen.plugin.dao.VersionStageRepositoryFactory;
+
+public class VersionStageRepositoryFactoryImpl extends VersionStageRepositoryFactory {
+
+  private static final VersionStageRepository INSTANCE = new VersionStageRepositoryImpl();
+
+  @Override
+  public VersionStageRepository createInterface(SessionContext context) {
+    return INSTANCE;
+  }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionStageRepositoryImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionStageRepositoryImpl.java
new file mode 100644
index 0000000..353f37b
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionStageRepositoryImpl.java
@@ -0,0 +1,82 @@
+package org.openecomp.core.zusammen.plugin.dao.impl.cassandra;
+
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.item.Action;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.mapping.annotations.Accessor;
+import com.datastax.driver.mapping.annotations.Query;
+import org.openecomp.core.zusammen.plugin.dao.VersionStageRepository;
+import org.openecomp.core.zusammen.plugin.dao.types.StageEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionContext;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
+
+import java.util.Date;
+import java.util.Optional;
+
+public class VersionStageRepositoryImpl implements VersionStageRepository {
+
+  @Override
+  public Optional<StageEntity<VersionEntity>> get(SessionContext context,
+                                                  VersionContext entityContext,
+                                                  VersionEntity entity) {
+    Row row = getAccessor(context)
+        .get(entityContext.getSpace(), entityContext.getItemId().toString(),
+            entity.getId().toString()).one();
+    return row == null ? Optional.empty() : Optional.of(convertToVersionStage(entity, row));
+  }
+
+  @Override
+  public void create(SessionContext context, VersionContext entityContext,
+                     StageEntity<VersionEntity> stageEntity) {
+    VersionEntity entity = stageEntity.getEntity();
+    getAccessor(context).create(entityContext.getSpace(),
+        entityContext.getItemId().toString(),
+        entity.getId().toString(),
+        entity.getBaseId() == null ? null : entity.getBaseId().toString(),
+        entity.getCreationTime() == null ? null : entity.getCreationTime(),
+        entity.getModificationTime() == null ? null : entity.getModificationTime(),
+        stageEntity.getPublishTime(),
+        stageEntity.getAction());
+  }
+
+  @Override
+  public void delete(SessionContext context, VersionContext entityContext, VersionEntity entity) {
+    getAccessor(context).delete(entityContext.getSpace(), entityContext.getItemId().toString(),
+        entity.getId().toString());
+  }
+
+  private StageEntity<VersionEntity> convertToVersionStage(VersionEntity version, Row row) {
+    StageEntity<VersionEntity> versionStage =
+        new StageEntity<>(VersionDaoImpl.enrichVersionEntity(version, row),
+            row.getDate(VersionStageField.PUBLISH_TIME));
+    versionStage.setAction(Action.valueOf(row.getString(VersionStageField.ACTION)));
+    return versionStage;
+  }
+
+  private VersionStageAccessor getAccessor(SessionContext context) {
+    return CassandraDaoUtils.getAccessor(context, VersionStageAccessor.class);
+  }
+
+  @Accessor
+  interface VersionStageAccessor {
+
+    @Query("INSERT INTO version_stage (space, item_id, version_id, base_version_id, " +
+        "creation_time, modification_time, publish_time, action) " +
+        "VALUES (?, ?, ?, ?, ?, ?, ?, ?)")
+    void create(String space, String itemId, String versionId, String baseVersionId,
+                Date creationTime, Date modificationTime, Date publishTime, Action action);
+
+    @Query("DELETE FROM version_stage WHERE space=? AND item_id=? AND version_id=?")
+    void delete(String space, String itemId, String versionId);
+
+    @Query("SELECT base_version_id, creation_time, modification_time, publish_time, action " +
+        "FROM  version_stage WHERE space=? AND item_id=? AND version_id=?")
+    ResultSet get(String space, String itemId, String versionId);
+  }
+
+  private static final class VersionStageField {
+    private static final String PUBLISH_TIME = "publish_time";
+    private static final String ACTION = "action";
+  }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionSynchronizationStateRepositoryFactoryImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionSynchronizationStateRepositoryFactoryImpl.java
new file mode 100644
index 0000000..95c3ec2
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionSynchronizationStateRepositoryFactoryImpl.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright © 2016-2017 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.core.zusammen.plugin.dao.impl.cassandra;
+
+import com.amdocs.zusammen.datatypes.SessionContext;
+import org.openecomp.core.zusammen.plugin.dao.VersionSynchronizationStateRepository;
+import org.openecomp.core.zusammen.plugin.dao.VersionSynchronizationStateRepositoryFactory;
+
+public class VersionSynchronizationStateRepositoryFactoryImpl
+    extends VersionSynchronizationStateRepositoryFactory {
+
+  private static final VersionSynchronizationStateRepository INSTANCE =
+      new VersionSynchronizationStateRepositoryImpl();
+
+  @Override
+  public VersionSynchronizationStateRepository createInterface(SessionContext context) {
+    return INSTANCE;
+  }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionSynchronizationStateRepositoryImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionSynchronizationStateRepositoryImpl.java
new file mode 100644
index 0000000..5fb9779
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/impl/cassandra/VersionSynchronizationStateRepositoryImpl.java
@@ -0,0 +1,137 @@
+package org.openecomp.core.zusammen.plugin.dao.impl.cassandra;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.mapping.annotations.Accessor;
+import com.datastax.driver.mapping.annotations.Query;
+import org.openecomp.core.zusammen.plugin.dao.VersionSynchronizationStateRepository;
+import org.openecomp.core.zusammen.plugin.dao.types.SynchronizationStateEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionContext;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+public class VersionSynchronizationStateRepositoryImpl
+    implements VersionSynchronizationStateRepository {
+
+  @Override
+  public void create(SessionContext context, VersionContext entityContext,
+                     SynchronizationStateEntity syncStateEntity) {
+    updatePublishTime(context, entityContext, syncStateEntity);
+  }
+
+  @Override
+  public void updatePublishTime(SessionContext context, VersionContext entityContext,
+                                SynchronizationStateEntity syncStateEntity) {
+    getAccessor(context)
+        .updatePublishTime(syncStateEntity.getPublishTime(), entityContext.getSpace(),
+            entityContext.getItemId().toString(), syncStateEntity.getId().toString(),
+            syncStateEntity.getRevisionId().getValue());
+  }
+
+  @Override
+  public List<SynchronizationStateEntity> list(SessionContext context, VersionContext
+      entityContext, VersionEntity versionEntity) {
+
+    List<Row> rows = getAccessor(context).list(entityContext.getSpace(), entityContext.getItemId().toString
+        (),versionEntity.getId().toString()).all();
+    return rows == null ? new ArrayList<>():
+        rows.stream().map(VersionSynchronizationStateRepositoryImpl::getSynchronizationStateEntity).collect(Collectors.toList());
+  }
+
+
+
+  /*@Override
+  public List<SynchronizationStateEntity> listRevisions(SessionContext context,
+                                                        VersionContext entityContext,
+                                                        SynchronizationStateEntity syncStateEntity) {
+    List<Row> rows = getAccessor(context).list(entityContext.getSpace(), entityContext.getItemId()
+        .toString(), syncStateEntity.getId().toString()).all();
+    return rows == null ? new ArrayList<>() :rows.stream()
+        .map(VersionSynchronizationStateRepositoryImpl::getSynchronizationStateEntity)
+        .collect(Collectors.toList());
+
+
+
+
+    //forEach(row -> getSynchronizationStateEntity(syncStateEntity.getId(), row));
+
+
+  }*/
+
+
+  @Override
+  public void delete(SessionContext context, VersionContext entityContext,
+                     SynchronizationStateEntity syncStateEntity) {
+    // done by version dao
+  }
+
+  @Override
+  public Optional<SynchronizationStateEntity> get(SessionContext context,
+                                                  VersionContext entityContext,
+                                                  SynchronizationStateEntity syncStateEntity) {
+    Row row =
+        getAccessor(context).get(entityContext.getSpace(), entityContext.getItemId().toString(),
+            syncStateEntity.getId().toString(), syncStateEntity.getRevisionId().getValue()).one();
+
+    return row == null ? Optional.empty()
+        : Optional.of(getSynchronizationStateEntity(syncStateEntity.getId(), row));
+  }
+
+  private SynchronizationStateEntity getSynchronizationStateEntity(Id entityId, Row row) {
+    SynchronizationStateEntity syncStateEntity = new SynchronizationStateEntity(entityId,
+        new Id(row.getString(REVISION_ID_FIELD)));
+    syncStateEntity.setPublishTime(row.getDate(PUBLISH_TIME_FIELD));
+    syncStateEntity.setDirty(!row.getSet(DIRTY_ELEMENT_FIELD, String.class).isEmpty());
+    return syncStateEntity;
+  }
+
+  private static SynchronizationStateEntity getSynchronizationStateEntity(Row row) {
+    Id entityId = new Id(row.getColumnDefinitions().contains("version_id") ? row.getString
+        ("version_id") : row.getString("element_id"));
+    SynchronizationStateEntity syncStateEntity = new SynchronizationStateEntity(entityId,
+        new Id(row.getString(REVISION_ID_FIELD)));
+    syncStateEntity.setPublishTime(row.getDate(PUBLISH_TIME_FIELD));
+    syncStateEntity.setDirty(!row.getSet(DIRTY_ELEMENT_FIELD, String.class).isEmpty());
+    syncStateEntity.setRevisionId(new Id(row.getString(REVISION_ID_FIELD)));
+    syncStateEntity.setUser(row.getString(USER));
+    syncStateEntity.setMessage(row.getString(MESSAGE));
+    return syncStateEntity;
+  }
+
+  private VersionSyncStateAccessor getAccessor(SessionContext context) {
+    return CassandraDaoUtils.getAccessor(context, VersionSyncStateAccessor.class);
+  }
+
+  @Accessor
+  interface VersionSyncStateAccessor {
+    @Query(
+        "UPDATE version_elements SET publish_time=? WHERE space=? AND item_id=? AND version_id=? " +
+            "AND revision_id=? ")
+    void updatePublishTime(Date publishTime, String space, String itemId, String versionId, String
+        revisionId);
+
+    @Query("SELECT version_id,revision_id,publish_time, dirty_element_ids FROM version_elements " +
+        "WHERE space=? AND item_id=? AND version_id=? AND revision_id=? ")
+    ResultSet get(String space, String itemId, String versionId, String revisionId);
+
+    @Query("SELECT version_id,revision_id,publish_time,user,message, dirty_element_ids FROM " +
+        "version_elements " +
+        "WHERE space=? AND item_id=? AND version_id=? ")
+    ResultSet list(String space, String itemId, String versionId);
+
+  }
+
+
+  private static final String PUBLISH_TIME_FIELD = "publish_time";
+  private static final String DIRTY_ELEMENT_FIELD = "dirty_element_ids";
+  private static final String REVISION_ID_FIELD = "revision_id";
+  private static final String USER = "user";
+  private static final String MESSAGE = "message";
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/ElementEntity.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/ElementEntity.java
index 1663d83..1cd1510 100644
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/ElementEntity.java
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/ElementEntity.java
@@ -30,6 +30,7 @@
   private Id id;
   private Id parentId;
   private Namespace namespace;
+  private Id elementHash;
   private Info info;
   private Collection<Relation> relations = Collections.emptyList();
   private ByteBuffer data;
@@ -41,6 +42,10 @@
     this.id = id;
   }
 
+  public Id getId() {
+    return id;
+  }
+
   public Id getParentId() {
     return parentId;
   }
@@ -49,14 +54,6 @@
     this.parentId = parentId;
   }
 
-  public Id getId() {
-    return id;
-  }
-
-  public void setId(Id id) {
-    this.id = id;
-  }
-
   public Namespace getNamespace() {
     return namespace;
   }
@@ -127,8 +124,17 @@
     return id.equals(that.id);
   }
 
+  public Id getElementHash() {
+    return elementHash;
+  }
+
+  public void setElementHash(Id elementHash) {
+    this.elementHash = elementHash;
+  }
+
   @Override
   public int hashCode() {
     return id.hashCode();
   }
+
 }
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/StageEntity.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/StageEntity.java
new file mode 100644
index 0000000..58ac0a9
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/StageEntity.java
@@ -0,0 +1,60 @@
+package org.openecomp.core.zusammen.plugin.dao.types;
+
+import com.amdocs.zusammen.datatypes.item.Action;
+
+import java.util.Collections;
+import java.util.Date;
+import java.util.Set;
+
+public class StageEntity<E> {
+  private E entity;
+  private Date publishTime;
+  private Action action = Action.IGNORE;
+  private boolean conflicted;
+  private Set<E> conflictDependents = Collections.emptySet();
+
+  // used by sync on stage creation
+  public StageEntity(E entity, Date publishTime) {
+    this.entity = entity;
+    this.publishTime = publishTime;
+  }
+
+  public StageEntity(E entity, Date publishTime, Action action, boolean conflicted) {
+    this.entity = entity;
+    this.publishTime = publishTime;
+    this.action = action;
+    this.conflicted = conflicted;
+  }
+
+  public E getEntity() {
+    return entity;
+  }
+
+  public Date getPublishTime() {
+    return publishTime;
+  }
+
+  public Action getAction() {
+    return action;
+  }
+
+  public void setAction(Action action) {
+    this.action = action;
+  }
+
+  public boolean isConflicted() {
+    return conflicted;
+  }
+
+  public void setConflicted(boolean conflicted) {
+    this.conflicted = conflicted;
+  }
+
+  public Set<E> getConflictDependents() {
+    return conflictDependents;
+  }
+
+  public void setConflictDependents(Set<E> conflictDependents) {
+    this.conflictDependents = conflictDependents;
+  }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/SynchronizationStateEntity.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/SynchronizationStateEntity.java
new file mode 100644
index 0000000..510cef8
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/SynchronizationStateEntity.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright © 2016-2017 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.core.zusammen.plugin.dao.types;
+
+import com.amdocs.zusammen.datatypes.Id;
+
+import java.util.Date;
+
+/**
+ * Synchronization state of an entity:
+ * <ul>
+ * <li>On private entity edit (create/update/delete): marked as dirty</li>
+ * <li>On entity publication:
+ * <ul>
+ * <li>if the private entity exists - updated with the publish time, marked as not dirty</li>
+ * <li>Otherwise - deleted</li>
+ * </ul>
+ * </li>
+ * </ul>
+ */
+public class SynchronizationStateEntity {
+  private Id id;
+  private Id revisionId;
+  private Date publishTime;
+  private boolean dirty;
+  private String user;
+  private String message;
+
+  public SynchronizationStateEntity(Id id,Id revisionId) {
+    this.id = id;
+    this.revisionId = revisionId;
+  }
+
+  public SynchronizationStateEntity(Id id,Id revisionId, Date publishTime, boolean dirty) {
+    this(id,revisionId);
+    this.publishTime = publishTime;
+    this.dirty = dirty;
+  }
+
+  public Id getId() {
+    return id;
+  }
+
+  public Date getPublishTime() {
+    return publishTime;
+  }
+
+  public void setPublishTime(Date publishTime) {
+    this.publishTime = publishTime;
+  }
+
+  public boolean isDirty() {
+    return dirty;
+  }
+
+  public void setDirty(boolean dirty) {
+    this.dirty = dirty;
+  }
+
+  public Id getRevisionId() {
+    return revisionId;
+  }
+
+  public void setRevisionId(Id revisionId) {
+    this.revisionId = revisionId;
+  }
+
+  public String getUser() {
+    return user;
+  }
+
+  public void setUser(String user) {
+    this.user = user;
+  }
+
+  public String getMessage() {
+    return message;
+  }
+
+  public void setMessage(String message) {
+    this.message = message;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+
+    SynchronizationStateEntity that = (SynchronizationStateEntity) o;
+
+    return id.equals(that.id);
+  }
+
+  @Override
+  public int hashCode() {
+    return id.hashCode();
+  }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/VersionContext.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/VersionContext.java
new file mode 100644
index 0000000..41a3e66
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/VersionContext.java
@@ -0,0 +1,23 @@
+package org.openecomp.core.zusammen.plugin.dao.types;
+
+import com.amdocs.zusammen.datatypes.Id;
+
+public class VersionContext {
+  private String space;
+  private Id itemId;
+
+
+  public VersionContext(String space, Id itemId) {
+    this.space = space;
+    this.itemId = itemId;
+  }
+
+  public String getSpace() {
+    return space;
+  }
+
+  public Id getItemId() {
+    return itemId;
+  }
+
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/VersionDataElement.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/VersionDataElement.java
new file mode 100644
index 0000000..48a52c0
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/VersionDataElement.java
@@ -0,0 +1,21 @@
+package org.openecomp.core.zusammen.plugin.dao.types;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.item.ItemVersionData;
+import org.openecomp.core.zusammen.plugin.ZusammenPluginConstants;
+
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.calculateElementHash;
+
+public class VersionDataElement extends ElementEntity {
+
+  public VersionDataElement() {
+    super(ZusammenPluginConstants.ROOT_ELEMENTS_PARENT_ID);
+  }
+
+  public VersionDataElement(ItemVersionData itemVersionData) {
+    this();
+    setInfo(itemVersionData.getInfo());
+    setRelations(itemVersionData.getRelations());
+    setElementHash(new Id(calculateElementHash(this)));
+  }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/VersionEntity.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/VersionEntity.java
new file mode 100644
index 0000000..aeed998
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/dao/types/VersionEntity.java
@@ -0,0 +1,45 @@
+package org.openecomp.core.zusammen.plugin.dao.types;
+
+import com.amdocs.zusammen.datatypes.Id;
+
+import java.util.Date;
+
+public class VersionEntity {
+  private Id id;
+  private Id baseId;
+  private Date creationTime;
+  private Date modificationTime;
+
+  public VersionEntity(Id id) {
+    this.id = id;
+  }
+
+  public Id getId() {
+    return id;
+  }
+
+  public Id getBaseId() {
+    return baseId;
+  }
+
+  public void setBaseId(Id baseId) {
+    this.baseId = baseId;
+  }
+
+  public Date getCreationTime() {
+    return creationTime;
+  }
+
+  public void setCreationTime(Date creationTime) {
+    this.creationTime = creationTime;
+  }
+
+  public Date getModificationTime() {
+    return modificationTime;
+  }
+
+  public void setModificationTime(Date modificationTime) {
+    this.modificationTime = modificationTime;
+  }
+
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/main/CassandraCollaborationStorePluginImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/main/CassandraCollaborationStorePluginImpl.java
index 90fd336..f9b6522 100644
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/main/CassandraCollaborationStorePluginImpl.java
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/main/CassandraCollaborationStorePluginImpl.java
@@ -21,132 +21,297 @@
 import com.amdocs.zusammen.datatypes.Id;
 import com.amdocs.zusammen.datatypes.Namespace;
 import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.Space;
+import com.amdocs.zusammen.datatypes.item.Action;
 import com.amdocs.zusammen.datatypes.item.ElementContext;
 import com.amdocs.zusammen.datatypes.item.Info;
+import com.amdocs.zusammen.datatypes.item.ItemVersion;
 import com.amdocs.zusammen.datatypes.item.ItemVersionData;
-import com.amdocs.zusammen.datatypes.itemversion.ItemVersionHistory;
+import com.amdocs.zusammen.datatypes.item.ItemVersionDataConflict;
+import com.amdocs.zusammen.datatypes.item.ItemVersionStatus;
+import com.amdocs.zusammen.datatypes.item.Resolution;
+import com.amdocs.zusammen.datatypes.itemversion.ItemVersionRevisions;
+import com.amdocs.zusammen.datatypes.itemversion.Revision;
 import com.amdocs.zusammen.datatypes.itemversion.Tag;
+import com.amdocs.zusammen.datatypes.response.ErrorCode;
+import com.amdocs.zusammen.datatypes.response.Module;
 import com.amdocs.zusammen.datatypes.response.Response;
+import com.amdocs.zusammen.datatypes.response.ReturnCode;
 import com.amdocs.zusammen.datatypes.response.ZusammenException;
 import com.amdocs.zusammen.sdk.collaboration.CollaborationStore;
 import com.amdocs.zusammen.sdk.collaboration.types.CollaborationElement;
+import com.amdocs.zusammen.sdk.collaboration.types.CollaborationElementChange;
+import com.amdocs.zusammen.sdk.collaboration.types.CollaborationElementConflict;
+import com.amdocs.zusammen.sdk.collaboration.types.CollaborationItemVersionConflict;
 import com.amdocs.zusammen.sdk.collaboration.types.CollaborationMergeChange;
 import com.amdocs.zusammen.sdk.collaboration.types.CollaborationMergeResult;
 import com.amdocs.zusammen.sdk.collaboration.types.CollaborationPublishResult;
-import org.openecomp.core.zusammen.plugin.collaboration.ElementCollaborationStore;
-import org.openecomp.core.zusammen.plugin.collaboration.VersionCollaborationStore;
+import com.amdocs.zusammen.sdk.types.ElementConflictDescriptor;
+import com.amdocs.zusammen.sdk.types.ElementDescriptor;
+import org.openecomp.core.zusammen.plugin.ZusammenPluginUtil;
+import org.openecomp.core.zusammen.plugin.collaboration.CommitStagingService;
+import org.openecomp.core.zusammen.plugin.collaboration.ElementPrivateStore;
+import org.openecomp.core.zusammen.plugin.collaboration.ElementPublicStore;
+import org.openecomp.core.zusammen.plugin.collaboration.ElementStageStore;
+import org.openecomp.core.zusammen.plugin.collaboration.PublishService;
+import org.openecomp.core.zusammen.plugin.collaboration.RevertService;
+import org.openecomp.core.zusammen.plugin.collaboration.SyncService;
+import org.openecomp.core.zusammen.plugin.collaboration.VersionPrivateStore;
+import org.openecomp.core.zusammen.plugin.collaboration.VersionPublicStore;
+import org.openecomp.core.zusammen.plugin.collaboration.VersionStageStore;
+import org.openecomp.core.zusammen.plugin.collaboration.impl.ElementPrivateStoreImpl;
+import org.openecomp.core.zusammen.plugin.collaboration.impl.ElementPublicStoreImpl;
+import org.openecomp.core.zusammen.plugin.collaboration.impl.ElementStageStoreImpl;
+import org.openecomp.core.zusammen.plugin.collaboration.impl.VersionPrivateStoreImpl;
+import org.openecomp.core.zusammen.plugin.collaboration.impl.VersionPublicStoreImpl;
+import org.openecomp.core.zusammen.plugin.collaboration.impl.VersionStageStoreImpl;
+import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.StageEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.SynchronizationStateEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionDataElement;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
 
 import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import static com.amdocs.zusammen.datatypes.item.SynchronizationStatus.MERGING;
+import static com.amdocs.zusammen.datatypes.item.SynchronizationStatus.OUT_OF_SYNC;
+import static com.amdocs.zusammen.datatypes.item.SynchronizationStatus.UP_TO_DATE;
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginConstants.ROOT_ELEMENTS_PARENT_ID;
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.convertToCollaborationElement;
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.convertToElementChange;
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.convertToElementDescriptor;
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.convertToElementEntity;
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.convertToItemVersion;
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.convertToVersionData;
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.convertToVersionEntity;
 
 public class CassandraCollaborationStorePluginImpl implements CollaborationStore {
+  // TODO: 8/15/2017 inject
 
-  private VersionCollaborationStore versionCollaborationStore = new VersionCollaborationStore();
-  private ElementCollaborationStore elementCollaborationStore = new ElementCollaborationStore();
+  private VersionPrivateStore versionPrivateStore = new VersionPrivateStoreImpl();
+  private VersionPublicStore versionPublicStore = new VersionPublicStoreImpl();
+  private VersionStageStore versionStageStore = new VersionStageStoreImpl();
+
+  private ElementPrivateStore elementPrivateStore = new ElementPrivateStoreImpl();
+  private ElementPublicStore elementPublicStore = new ElementPublicStoreImpl();
+  private ElementStageStore elementStageStore = new ElementStageStoreImpl();
+
+  // TODO: 9/4/2017
+  private CommitStagingService commitStagingService =
+      new CommitStagingService(versionPrivateStore, versionStageStore, elementPrivateStore,
+          elementStageStore);
+  private PublishService publishService =
+      new PublishService(versionPublicStore, versionPrivateStore, elementPublicStore,
+          elementPrivateStore);
+  private SyncService syncService =
+      new SyncService(versionPublicStore, versionPrivateStore, versionStageStore,
+          elementPublicStore, elementPrivateStore, elementStageStore);
+
+  private RevertService revertService =
+      new RevertService(elementPublicStore, elementPrivateStore);
 
   @Override
-  public Response<Void> createItem(SessionContext context, Id id, Info info) {
+  public Response<Void> createItem(SessionContext context, Id itemId, Info info) {
     // done by state store
     return new Response(Void.TYPE);
   }
 
   @Override
-  public Response<Void> deleteItem(SessionContext context, Id id) {
+  public Response<Void> deleteItem(SessionContext context, Id itemId) {
     // done by state store
     return new Response(Void.TYPE);
   }
 
   @Override
-  public Response<Void> createItemVersion(SessionContext context, Id itemId, Id versionId, Id id2,
-                                          ItemVersionData itemVersionData) {
-    // done by state store
+  public Response<Void> createItemVersion(SessionContext context, Id itemId, Id baseVersionId,
+                                          Id versionId, ItemVersionData itemVersionData) {
+    Date creationTime = new Date();
+    versionPrivateStore.create(context, itemId,
+        convertToVersionEntity(versionId, baseVersionId, creationTime, creationTime));
+
+    ElementContext elementContext = new ElementContext(itemId, versionId);
+    VersionDataElement versionData = new VersionDataElement(itemVersionData);
+
+    if (baseVersionId == null) {
+      elementPrivateStore.create(context, elementContext, versionData);
+    } else {
+      copyElements(context, new ElementContext(itemId, baseVersionId), elementContext);
+      elementPrivateStore.update(context, elementContext, versionData);
+    }
+
     return new Response(Void.TYPE);
   }
 
   @Override
   public Response<Void> updateItemVersion(SessionContext context, Id itemId, Id versionId,
                                           ItemVersionData itemVersionData) {
-    // done by state store
+
+    if (elementPrivateStore.update(context, new ElementContext(itemId, versionId),
+        new VersionDataElement(itemVersionData))) {
+
+      VersionEntity version = new VersionEntity(versionId);
+      version.setModificationTime(new Date());
+      versionPrivateStore.update(context, itemId, version);
+    }
+
     return new Response(Void.TYPE);
   }
 
   @Override
   public Response<Void> deleteItemVersion(SessionContext context, Id itemId, Id versionId) {
-    // done by state store
+    elementPrivateStore
+        .delete(context, new ElementContext(itemId, versionId), new VersionDataElement());
+
+    versionPrivateStore.delete(context, itemId, new VersionEntity(versionId));
     return new Response(Void.TYPE);
   }
 
   @Override
-  public Response<Void> tagItemVersion(SessionContext context, Id itemId, Id versionId, Id changeId,
+  public Response<ItemVersionStatus> getItemVersionStatus(SessionContext context, Id itemId,
+                                                          Id versionId) {
+    if (versionStageStore.get(context, itemId, new VersionEntity(versionId)).isPresent()) {
+      return new Response<>(new ItemVersionStatus(MERGING, true));
+    }
+
+    Optional<SynchronizationStateEntity> publicSyncState =
+        versionPublicStore.getSynchronizationState(context, itemId, versionId);
+
+    if (!publicSyncState.isPresent()) {
+      return new Response<>(new ItemVersionStatus(UP_TO_DATE, true));
+    }
+
+    SynchronizationStateEntity privateSyncState =
+        versionPrivateStore.getSynchronizationState(context, itemId, versionId)
+            // TODO: 7/18/2017 ?
+            .orElseThrow(() -> new IllegalStateException("private version must exist"));
+
+    return new Response<>(new ItemVersionStatus(
+        privateSyncState.getPublishTime().equals(publicSyncState.get().getPublishTime())
+            ? UP_TO_DATE
+            : OUT_OF_SYNC,
+        privateSyncState.isDirty()));
+  }
+
+  @Override
+  public Response<Void> tagItemVersion(SessionContext context, Id itemId, Id versionId,
+                                       Id revisionId,
                                        Tag tag) {
-    versionCollaborationStore.tagItemVersion(context, itemId, versionId, changeId, tag);
+   /* if (revisionId != null) {
+      throw new UnsupportedOperationException(
+          "In this plugin implementation tag is supported only on versionId");
+    }
+
+    copyElements(context,
+        new ElementContext(itemId, versionId),
+        new ElementContext(itemId, versionId, tag.getName()));*/
+
     return new Response(Void.TYPE);
   }
 
   @Override
   public Response<CollaborationPublishResult> publishItemVersion(SessionContext context,
                                                                  Id itemId, Id versionId,
-                                                                 String s) {
-    throw new UnsupportedOperationException("publishItemVersion");
+                                                                 String message) {
+    try {
+      return new Response<>(publishService.publish(context, itemId, versionId, message));
+    } catch (ZusammenException ze) {
+      return new Response<>(
+          new ReturnCode(ErrorCode.CL_ITEM_VERSION_PUBLISH, Module.ZCSP, null, ze.getReturnCode()));
+    }
   }
 
   @Override
-  public Response<CollaborationMergeResult> syncItemVersion(SessionContext context, Id id,
-                                                            Id id1) {
-    throw new UnsupportedOperationException("syncItemVersion");
+  public Response<CollaborationMergeResult> syncItemVersion(SessionContext context, Id itemId,
+                                                            Id versionId) {
+    CollaborationMergeResult result = syncService.sync(context, itemId, versionId, false);
+    commitStagingService.commitStaging(context, itemId, versionId);
+
+    return new Response<>(result);
   }
 
   @Override
-  public Response<CollaborationMergeResult> mergeItemVersion(SessionContext context, Id id,
-                                                             Id id1, Id id2) {
+  public Response<CollaborationMergeResult> forceSyncItemVersion(SessionContext context, Id itemId,
+                                                                 Id versionId) {
+    CollaborationMergeResult result = syncService.sync(context, itemId, versionId, true);
+    commitStagingService.commitStaging(context, itemId, versionId);
+
+    return new Response<>(result);
+  }
+
+  @Override
+  public Response<CollaborationMergeResult> mergeItemVersion(SessionContext context, Id itemId,
+                                                             Id versionId, Id sourceVersionId) {
     throw new UnsupportedOperationException("mergeItemVersion");
   }
 
   @Override
-  public Response<ItemVersionHistory> listItemVersionHistory(SessionContext context, Id id,
-                                                             Id id1) {
-    throw new UnsupportedOperationException("listItemVersionHistory");
+  public Response<CollaborationItemVersionConflict> getItemVersionConflict(SessionContext context,
+                                                                           Id itemId,
+                                                                           Id versionId) {
+    ElementContext elementContext = new ElementContext(itemId, versionId, Id.ZERO);
+
+    Collection<StageEntity<ElementEntity>> conflictedStagedElementDescriptors =
+        elementStageStore.listConflictedDescriptors(context, elementContext);
+
+    CollaborationItemVersionConflict result = new CollaborationItemVersionConflict();
+    for (StageEntity<ElementEntity> stagedElementDescriptor : conflictedStagedElementDescriptors) {
+      if (ROOT_ELEMENTS_PARENT_ID.equals(stagedElementDescriptor.getEntity().getId())) {
+        result.setVersionDataConflict(
+            getVersionDataConflict(context, elementContext, stagedElementDescriptor));
+      } else {
+        result.getElementConflictDescriptors()
+            .add(getElementConflictDescriptor(context, elementContext, stagedElementDescriptor));
+      }
+    }
+    return new Response<>(result);
   }
 
   @Override
-  public Response<CollaborationMergeChange> resetItemVersionHistory(SessionContext context,
-                                                                    Id itemId, Id versionId,
-                                                                    String changeRef) {
-    return new Response<>(versionCollaborationStore.resetItemVersionHistory(context, itemId, versionId, changeRef));
+  public Response<ItemVersionRevisions> listItemVersionRevisions(SessionContext context, Id itemId,
+                                                                 Id versionId) {
+    return new Response<>(versionPublicStore.listItemVersionRevisions(context, itemId, versionId));
   }
 
   @Override
-  public Response<Collection<CollaborationElement>> listElements(SessionContext context,
-                                                                 ElementContext elementContext,
-                                                                 Namespace namespace,
-                                                                 Id elementId) {
-    return new Response<>(
-        elementCollaborationStore.listElements(context, elementContext, elementId));
+  public Response<Revision> getItemVersionRevision(SessionContext context, Id itemId, Id versionId,
+                                                   Id revisionId) {
+    throw new UnsupportedOperationException(
+        "get revision is not supported in the current cassandra plugin");
   }
 
   @Override
-  public Response<CollaborationElement> getElement(SessionContext context,
-                                                   ElementContext elementContext,
-                                                   Namespace namespace, Id elementId) {
-    return new Response<>(elementCollaborationStore.getElement(context, elementContext, elementId));
+  public Response<CollaborationMergeChange> resetItemVersionRevision(SessionContext context,
+                                                                     Id itemId, Id versionId,
+                                                                     Id revisionId) {
+    throw new UnsupportedOperationException("resetItemVersionRevision function not supported");
+
   }
 
   @Override
-  public Response<Void> createElement(SessionContext context, CollaborationElement element) {
-    elementCollaborationStore.createElement(context, element);
-    return new Response(Void.TYPE);
+  public Response<CollaborationMergeChange> revertItemVersionRevision(SessionContext context,
+                                                                      Id itemId, Id versionId,
+                                                                      Id revisionId) {
+    Optional<ItemVersion> itemVersion = getItemVersion(context, itemId, versionId, revisionId);
+    if (!itemVersion.isPresent()) {
+      throw new RuntimeException(String
+          .format("Item %s, version %s: Cannot revert to revision %s since it is not found",
+              itemId, versionId, revisionId));
+    }
+
+    // TODO: 12/4/2017 force sync is done in order to clear dirty element on private
+    // this is temp solution that should be fixed.
+    forceSyncItemVersion(context, itemId, versionId);
+
+    //updateItemVersion(context, itemId, versionId, itemVersion.get().getData());
+    revertService.revert(context, itemId, versionId, revisionId);
+
+    return new Response<>(new CollaborationMergeChange());
   }
 
-  @Override
-  public Response<Void> updateElement(SessionContext context, CollaborationElement element) {
-    elementCollaborationStore.updateElement(context, element);
-    return new Response(Void.TYPE);
-  }
-
-  @Override
-  public Response<Void> deleteElement(SessionContext context, CollaborationElement element) {
-    elementCollaborationStore.deleteElement(context, element);
-    return new Response(Void.TYPE);
-  }
 
   @Override
   public Response<Void> commitElements(SessionContext context, Id itemId, Id versionId, String s) {
@@ -155,16 +320,202 @@
   }
 
   @Override
-  public Response<HealthInfo> checkHealth(SessionContext sessionContext) throws ZusammenException {
+  public Response<Collection<CollaborationElement>> listElements(SessionContext context,
+                                                                 ElementContext elementContext,
+                                                                 Namespace namespace,
+                                                                 Id elementId) {
+    return new Response<>(elementPrivateStore.listSubs(context, elementContext, elementId).stream()
+        .map(elementEntity -> convertToCollaborationElement(elementContext, elementEntity))
+        .collect(Collectors.toList()));
+  }
 
-    boolean health = elementCollaborationStore.checkHealth(sessionContext);
-    HealthInfo healthInfo ;
-    if (health){
-      healthInfo = new HealthInfo("Collaboration", HealthStatus.UP,"");
-    } else {
-      healthInfo = new HealthInfo("Collaboration", HealthStatus.DOWN,"No Schema Available");
+  @Override
+  public Response<CollaborationElement> getElement(SessionContext context,
+                                                   ElementContext elementContext,
+                                                   Namespace namespace, Id elementId) {
+    return new Response<>(elementPrivateStore.get(context, elementContext, elementId)
+        .map(elementEntity -> convertToCollaborationElement(elementContext, elementEntity))
+        .orElse(null));
+  }
+
+  @Override
+  public Response<CollaborationElementConflict> getElementConflict(SessionContext context,
+                                                                   ElementContext elementContext,
+                                                                   Namespace namespace,
+                                                                   Id elementId) {
+    Optional<StageEntity<ElementEntity>> conflictedStagedElement =
+        elementStageStore
+            .getConflicted(context, elementContext, new ElementEntity(elementId));
+
+    return new Response<>(conflictedStagedElement
+        .map(stagedElement -> getElementConflict(context, elementContext, stagedElement))
+        .orElse(null));
+  }
+
+  @Override
+  public Response<Void> createElement(SessionContext context, CollaborationElement element) {
+    elementPrivateStore.create(context,
+        new ElementContext(element.getItemId(), element.getVersionId()),
+        convertToElementEntity(element));
+    return new Response(Void.TYPE);
+  }
+
+  @Override
+  public Response<Void> updateElement(SessionContext context, CollaborationElement element) {
+    elementPrivateStore.update(context,
+        new ElementContext(element.getItemId(), element.getVersionId()),
+        convertToElementEntity(element));
+    return new Response(Void.TYPE);
+  }
+
+  @Override
+  public Response<Void> deleteElement(SessionContext context, CollaborationElement element) {
+    elementPrivateStore
+        .delete(context, new ElementContext(element.getItemId(), element.getVersionId()),
+            convertToElementEntity(element));
+
+    return new Response(Void.TYPE);
+  }
+
+  @Override
+  public Response<CollaborationMergeResult> resolveElementConflict(SessionContext context,
+                                                                   CollaborationElement element,
+                                                                   Resolution resolution) {
+    ElementContext elementContext = new ElementContext(element.getItemId(), element.getVersionId());
+    elementStageStore
+        .resolveConflict(context, elementContext, convertToElementEntity(element), resolution);
+    commitStagingService.commitStaging(context, element.getItemId(), element.getVersionId());
+
+    return new Response<>(new CollaborationMergeResult());
+  }
+
+  @Override
+  public Response<ItemVersion> getItemVersion(SessionContext context, Space space, Id itemId,
+                                              Id versionId, Id revisionId) {
+    return new Response<>(getItemVersion(context, itemId, versionId, revisionId).orElse(null));
+  }
+
+  @Override
+  public Response<HealthInfo> checkHealth(SessionContext context) throws ZusammenException {
+    HealthInfo healthInfo = versionPublicStore.checkHealth(context)
+        ? new HealthInfo(Module.ZCSP.getDescription(), HealthStatus.UP, "")
+        : new HealthInfo(Module.ZCSP.getDescription(), HealthStatus.DOWN, "No Schema Available");
+
+    return new Response<>(healthInfo);
+  }
+
+  private Optional<ItemVersion> getItemVersion(SessionContext context, Id itemId, Id versionId,
+                                               Id revisionId) {
+    // since revisions are kept only on public - get from there
+    Optional<VersionEntity> versionEntity = versionPublicStore.get(context, itemId, versionId);
+    if (!versionEntity.isPresent()) {
+      return Optional.empty();
     }
-    return new Response<HealthInfo>(healthInfo);
 
+    return elementPublicStore
+        .getDescriptor(context, new ElementContext(itemId, versionId, revisionId),
+            ROOT_ELEMENTS_PARENT_ID)
+        .map(ZusammenPluginUtil::convertToVersionData)
+        .map(itemVersionData -> convertToItemVersion(versionEntity.get(), itemVersionData));
+  }
+
+  private List<ElementEntity> listVersionElements(SessionContext context,
+                                                  ElementContext elementContext) {
+    return elementPrivateStore.listIds(context, elementContext).entrySet().stream() // TODO:
+        // 9/5/2017 parallel
+        .map(entry -> elementPrivateStore.get(context, elementContext, entry.getKey()).get())
+        .collect(Collectors.toList());
+  }
+
+  private void copyElements(SessionContext context,
+                            ElementContext sourceContext, ElementContext targetContext) {
+    listVersionElements(context, sourceContext).forEach(element -> {
+      // publishTime copied as is and dirty is off
+      Date publishTime =
+          elementPrivateStore.getSynchronizationState(context, sourceContext, element.getId())
+              .get().getPublishTime();
+      elementPrivateStore.commitStagedCreate(context, targetContext, element, publishTime);
+    });
+  }
+
+  private ItemVersionDataConflict getVersionDataConflict(SessionContext context,
+                                                         ElementContext elementContext,
+                                                         StageEntity<ElementEntity> stagedElementDescriptor) {
+    ItemVersionDataConflict versionConflict = new ItemVersionDataConflict();
+    versionConflict.setRemoteData(convertToVersionData(stagedElementDescriptor.getEntity()));
+    if (stagedElementDescriptor.getAction() == Action.UPDATE) {
+      versionConflict.setLocalData(getPrivateVersionData(context, elementContext));
+    }
+    return versionConflict;
+  }
+
+  private ItemVersionData getPrivateVersionData(SessionContext context,
+                                                ElementContext elementContext) {
+    return elementPrivateStore.getDescriptor(context, elementContext, ROOT_ELEMENTS_PARENT_ID)
+        .map(ZusammenPluginUtil::convertToVersionData)
+        .orElseThrow(() -> new IllegalStateException("Version must have data"));
+  }
+
+  private ElementConflictDescriptor getElementConflictDescriptor(SessionContext context,
+                                                                 ElementContext elementContext,
+                                                                 StageEntity<ElementEntity> stagedElementDescriptor) {
+    ElementDescriptor elementDescriptorFromStage =
+        convertToElementDescriptor(elementContext, (stagedElementDescriptor.getEntity()));
+
+    ElementConflictDescriptor conflictDescriptor = new ElementConflictDescriptor();
+    switch (stagedElementDescriptor.getAction()) {
+      case CREATE:
+        conflictDescriptor.setRemoteElementDescriptor(elementDescriptorFromStage);
+        break;
+      case UPDATE:
+        conflictDescriptor.setRemoteElementDescriptor(elementDescriptorFromStage);
+        conflictDescriptor.setLocalElementDescriptor(convertToElementDescriptor(elementContext,
+            elementPrivateStore
+                .getDescriptor(context, elementContext, stagedElementDescriptor.getEntity().getId())
+                .orElse(null)));// updated on public while deleted from private
+        break;
+      case DELETE:
+        conflictDescriptor.setLocalElementDescriptor(elementDescriptorFromStage);
+        break;
+      default:
+        break;
+    }
+    return conflictDescriptor;
+  }
+
+  private void addElementsToChangedElements(ElementContext elementContext,
+                                            Collection<ElementEntity> elements,
+                                            Collection<CollaborationElementChange> changedElements,
+                                            Action action) {
+    elements.stream()
+        .map(elementEntity -> convertToElementChange(elementContext, elementEntity, action))
+        .forEach(changedElements::add);
+  }
+
+  private CollaborationElementConflict getElementConflict(SessionContext context,
+                                                          ElementContext entityContext,
+                                                          StageEntity<ElementEntity> stagedElement) {
+    CollaborationElement elementFromStage =
+        convertToCollaborationElement(entityContext, (stagedElement.getEntity()));
+
+    CollaborationElementConflict conflict = new CollaborationElementConflict();
+    switch (stagedElement.getAction()) {
+      case CREATE:
+        conflict.setRemoteElement(elementFromStage);
+        break;
+      case UPDATE:
+        conflict.setRemoteElement(elementFromStage);
+        conflict.setLocalElement(
+            elementPrivateStore.get(context, entityContext, stagedElement.getEntity().getId())
+                .map(element -> convertToCollaborationElement(entityContext, element))
+                .orElse(null));// updated on public while deleted from private
+        break;
+      case DELETE:
+        conflict.setLocalElement(elementFromStage);
+        break;
+      default:
+        break;
+    }
+    return conflict;
   }
 }
\ No newline at end of file
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/main/CassandraStateStorePluginImpl.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/main/CassandraStateStorePluginImpl.java
index b4767b2..3ed668e 100644
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/main/CassandraStateStorePluginImpl.java
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/java/org/openecomp/core/zusammen/plugin/main/CassandraStateStorePluginImpl.java
@@ -17,18 +17,87 @@
 package org.openecomp.core.zusammen.plugin.main;
 
 
+import com.amdocs.zusammen.datatypes.Id;
 import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.Space;
+import com.amdocs.zusammen.datatypes.item.ElementContext;
+import com.amdocs.zusammen.datatypes.item.ItemVersion;
+import com.amdocs.zusammen.datatypes.item.ItemVersionData;
 import com.amdocs.zusammen.datatypes.response.Response;
 import com.amdocs.zusammen.plugin.statestore.cassandra.StateStoreImpl;
 import com.amdocs.zusammen.plugin.statestore.cassandra.dao.types.ElementEntityContext;
 import com.amdocs.zusammen.sdk.state.types.StateElement;
+import org.openecomp.core.zusammen.plugin.ZusammenPluginUtil;
+import org.openecomp.core.zusammen.plugin.collaboration.ElementPrivateStore;
+import org.openecomp.core.zusammen.plugin.collaboration.impl.ElementPrivateStoreImpl;
+import org.openecomp.core.zusammen.plugin.dao.ElementRepository;
 import org.openecomp.core.zusammen.plugin.dao.ElementRepositoryFactory;
+import org.openecomp.core.zusammen.plugin.dao.VersionDao;
+import org.openecomp.core.zusammen.plugin.dao.VersionDaoFactory;
 import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionDataElement;
+import org.openecomp.core.zusammen.plugin.dao.types.VersionEntity;
 
+import java.util.Collection;
+import java.util.Date;
+import java.util.stream.Collectors;
+
+import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.convertToItemVersion;
 import static org.openecomp.core.zusammen.plugin.ZusammenPluginUtil.getSpaceName;
 
 public class CassandraStateStorePluginImpl extends StateStoreImpl {
 
+  private ElementPrivateStore elementPrivateStore = new ElementPrivateStoreImpl();
+
+  @Override
+  public Response<Collection<ItemVersion>> listItemVersions(SessionContext context, Space space,
+                                                            Id itemId) {
+    String spaceName = getSpaceName(context, space);
+    return new Response<>(getVersionDao(context).list(context, spaceName, itemId).stream()
+        .map(versionEntity -> getItemVersion(context, spaceName, itemId, versionEntity))
+        .collect(Collectors.toList()));
+  }
+
+  @Override
+  public Response<Boolean> isItemVersionExist(SessionContext context, Space space, Id itemId,
+                                              Id versionId) {
+    return new Response<>(
+        getVersionDao(context).get(context, getSpaceName(context, space), itemId, versionId)
+            .isPresent());
+  }
+
+  @Override
+  public Response<ItemVersion> getItemVersion(SessionContext context, Space space, Id itemId,
+                                              Id versionId) {
+    String spaceName = getSpaceName(context, space);
+    return new Response<>(getVersionDao(context).get(context, spaceName, itemId, versionId)
+        .map(versionEntity -> getItemVersion(context, spaceName, itemId, versionEntity))
+        .orElse(null));
+  }
+
+  @Override
+  public Response<Void> createItemVersion(SessionContext context, Space space, Id itemId,
+                                          Id baseVersionId, Id versionId, ItemVersionData data,
+                                          Date creationTime) {
+    // done by collaboration store
+    return new Response(Void.TYPE);
+  }
+
+  @Override
+  public Response<Void> updateItemVersion(SessionContext context, Space space, Id itemId,
+                                          Id versionId, ItemVersionData data,
+                                          Date modificationTime) {
+    // done by collaboration store
+    return new Response(Void.TYPE);
+  }
+
+  @Override
+  public Response<Void> deleteItemVersion(SessionContext context, Space space, Id itemId,
+                                          Id versionId) {
+    // done by collaboration store
+    return new Response(Void.TYPE);
+  }
+
   @Override
   public Response<Void> createElement(SessionContext context, StateElement element) {
     ElementEntity elementEntity = new ElementEntity(element.getId());
@@ -37,8 +106,7 @@
     ElementRepositoryFactory.getInstance().createInterface(context)
         .createNamespace(context,
             new ElementEntityContext(getSpaceName(context, element.getSpace()),
-                element.getItemId(), element.getVersionId()),
-            elementEntity);
+                element.getItemId(), element.getVersionId()), elementEntity);
     // create element is done by collaboration store
     return new Response(Void.TYPE);
   }
@@ -55,4 +123,46 @@
     return new Response(Void.TYPE);
   }
 
+  @Override
+  public Response<Collection<StateElement>> listElements(SessionContext context,
+                                                         ElementContext elementContext,
+                                                         Id elementId) {
+    return new Response(elementPrivateStore.listSubs(context, elementContext, elementId).stream()
+        .map(elementEntity -> ZusammenPluginUtil.getStateElement(elementContext, elementEntity))
+        .collect(Collectors.toList()));
+
+  }
+
+  @Override
+  public Response<StateElement> getElement(SessionContext context, ElementContext elementContext,
+                                           Id elementId) {
+
+    return new Response(elementPrivateStore.get(context, elementContext, elementId)
+        .map(elementEntity -> ZusammenPluginUtil
+            .getStateElement(elementContext, elementEntity))
+        .orElse
+            (null));
+
+
+  }
+
+  private ItemVersion getItemVersion(SessionContext context, String spaceName, Id itemId,
+                                     VersionEntity versionEntity) {
+
+    ItemVersionData itemVersionData = getElementRepository(context)
+        .get(context, new ElementEntityContext(spaceName, itemId, versionEntity.getId(), null),
+            new VersionDataElement())
+        .map(ZusammenPluginUtil::convertToVersionData)
+        .orElseThrow(() -> new IllegalStateException("Version must have data"));
+
+    return convertToItemVersion(versionEntity, itemVersionData);
+  }
+
+  protected VersionDao getVersionDao(SessionContext context) {
+    return VersionDaoFactory.getInstance().createInterface(context);
+  }
+
+  protected ElementRepository getElementRepository(SessionContext context) {
+    return ElementRepositoryFactory.getInstance().createInterface(context);
+  }
 }
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/resources/factoryConfiguration.json b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/resources/factoryConfiguration.json
index cd1e293..841e005 100644
--- a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/resources/factoryConfiguration.json
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/main/resources/factoryConfiguration.json
@@ -1,3 +1,8 @@
 {
-  "org.openecomp.core.zusammen.plugin.dao.ElementRepositoryFactory": "org.openecomp.core.zusammen.plugin.dao.impl.CassandraElementRepositoryFactory"
+  "org.openecomp.core.zusammen.plugin.dao.VersionDaoFactory": "org.openecomp.core.zusammen.plugin.dao.impl.cassandra.VersionDaoFactoryImpl",
+  "org.openecomp.core.zusammen.plugin.dao.ElementRepositoryFactory": "org.openecomp.core.zusammen.plugin.dao.impl.cassandra.ElementRepositoryFactoryImpl",
+  "org.openecomp.core.zusammen.plugin.dao.VersionSynchronizationStateRepositoryFactory": "org.openecomp.core.zusammen.plugin.dao.impl.cassandra.VersionSynchronizationStateRepositoryFactoryImpl",
+  "org.openecomp.core.zusammen.plugin.dao.ElementSynchronizationStateRepositoryFactory": "org.openecomp.core.zusammen.plugin.dao.impl.cassandra.ElementSynchronizationStateRepositoryFactoryImpl",
+  "org.openecomp.core.zusammen.plugin.dao.VersionStageRepositoryFactory": "org.openecomp.core.zusammen.plugin.dao.impl.cassandra.VersionStageRepositoryFactoryImpl",
+  "org.openecomp.core.zusammen.plugin.dao.ElementStageRepositoryFactory": "org.openecomp.core.zusammen.plugin.dao.impl.cassandra.ElementStageRepositoryFactoryImpl"
 }
\ No newline at end of file
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/test/java/org/openecomp/core/zusammen/plugin/collaboration/TestUtils.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/test/java/org/openecomp/core/zusammen/plugin/collaboration/TestUtils.java
new file mode 100644
index 0000000..79e918c
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/test/java/org/openecomp/core/zusammen/plugin/collaboration/TestUtils.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright © 2016-2017 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.core.zusammen.plugin.collaboration;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.UserInfo;
+import com.amdocs.zusammen.datatypes.item.ElementContext;
+import com.amdocs.zusammen.datatypes.item.Info;
+import com.amdocs.zusammen.datatypes.item.ItemVersion;
+import com.amdocs.zusammen.datatypes.item.ItemVersionData;
+import com.amdocs.zusammen.datatypes.item.Relation;
+
+import java.util.Arrays;
+
+public class TestUtils {
+
+  public static SessionContext createSessionContext(UserInfo user, String tenant) {
+    SessionContext context = new SessionContext();
+    context.setUser(user);
+    context.setTenant(tenant);
+    return context;
+  }
+
+  public static ElementContext createElementContext(Id itemId, Id versionId) {
+    ElementContext elementContext = new ElementContext();
+    elementContext.setItemId(itemId);
+    elementContext.setVersionId(versionId);
+    return elementContext;
+  }
+
+  public static Info createInfo(String value) {
+    Info info = new Info();
+    info.setName(value);
+    info.addProperty("Name", "name_" + value);
+    info.addProperty("Desc", "desc_" + value);
+    return info;
+  }
+
+  public static ItemVersion createItemVersion(Id id, Id baseId, String name, boolean dirty) {
+    ItemVersion version = new ItemVersion();
+    version.setId(id);
+    version.setBaseId(baseId);
+    ItemVersionData data = new ItemVersionData();
+    data.setInfo(TestUtils.createInfo(name));
+    data.setRelations(Arrays.asList(new Relation(), new Relation()));
+    version.setData(data);
+    return version;
+  }
+}
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/test/java/org/openecomp/core/zusammen/plugin/collaboration/VersionCollaborationStoreTest.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/test/java/org/openecomp/core/zusammen/plugin/collaboration/VersionCollaborationStoreTest.java
new file mode 100644
index 0000000..4c4621e
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/test/java/org/openecomp/core/zusammen/plugin/collaboration/VersionCollaborationStoreTest.java
@@ -0,0 +1,237 @@
+package org.openecomp.core.zusammen.plugin.collaboration;
+
+public class VersionCollaborationStoreTest {/*
+  private static final String TENANT = "test";
+  private static final String USER = "ItemStateStoreTest_user";
+  private static final SessionContext context =
+      TestUtils.createSessionContext(new UserInfo(USER), TENANT);
+
+  @Mock
+  private VersionDao versionDaoMock;
+  @Mock
+  private ElementStore elementCollaborationStore;
+  @Spy
+  @InjectMocks
+  private VersionStore versionCollaborationStore;
+
+  @BeforeMethod
+  public void setUp() throws Exception {
+    MockitoAnnotations.initMocks(this);
+    when(versionCollaborationStore.getVersionDao(anyObject())).thenReturn(versionDaoMock);
+  }
+*//*
+  @Test
+  public void testListPrivateItemVersions() throws Exception {
+    testListItemVersions(Space.PRIVATE, USER);
+  }
+
+  @Test
+  public void testListPublicItemVersions() throws Exception {
+    testListItemVersions(Space.PUBLIC, ZusammenPluginConstants.PUBLIC_SPACE);
+  }
+
+  @Test
+  public void testIsPrivateItemVersionExist() throws Exception {
+    testIsItemVersionExist(Space.PRIVATE, USER);
+  }
+
+  @Test
+  public void testIsPublicItemVersionExist() throws Exception {
+    testIsItemVersionExist(Space.PUBLIC, ZusammenPluginConstants.PUBLIC_SPACE);
+  }
+
+  @Test
+  public void testIsItemVersionExistWhenNot() throws Exception {
+    Id itemId = new Id();
+    Id versionId = new Id();
+    doReturn(Optional.empty()).when(versionDaoMock).get(context, USER, itemId, versionId);
+
+    boolean itemExist =
+        versionCollaborationStore.isItemVersionExist(context, Space.PRIVATE, itemId, versionId);
+    Assert.assertFalse(itemExist);
+  }
+
+  @Test
+  public void testGetPrivateItemVersion() throws Exception {
+    testGetItemVersion(Space.PRIVATE, USER);
+  }
+
+  @Test
+  public void testGetPublicItemVersion() throws Exception {
+    testGetItemVersion(Space.PUBLIC, ZusammenPluginConstants.PUBLIC_SPACE);
+  }
+
+
+  @Test
+  public void testGetNonExistingItemVersion() throws Exception {
+    Id itemId = new Id();
+    Id versionId = new Id();
+    doReturn(Optional.empty()).when(versionDaoMock).get(context, USER, itemId, versionId);
+
+    ItemVersion itemVersion =
+        versionCollaborationStore.getItemVersion(context, Space.PRIVATE, itemId, versionId);
+    Assert.assertNull(itemVersion);
+  }*//*
+
+  @Test
+  public void testCreatePrivateItemVersion() throws Exception {
+    testCreateItemVersion(Space.PRIVATE, USER, null);
+  }
+
+  @Test
+  public void testCreatePrivateItemVersionBasedOn() throws Exception {
+    testCreateItemVersion(Space.PRIVATE, USER, new Id());
+  }
+
+  @Test
+  public void testCreatePublicItemVersion() throws Exception {
+    testCreateItemVersion(Space.PUBLIC, ZusammenPluginConstants.PUBLIC_SPACE, null);
+  }
+
+  @Test
+  public void testCreatePublicItemVersionBasedOn() throws Exception {
+    testCreateItemVersion(Space.PUBLIC, ZusammenPluginConstants.PUBLIC_SPACE, new Id());
+  }
+
+  @Test
+  public void testUpdatePrivateItemVersion() throws Exception {
+    testUpdateItemVersion(Space.PRIVATE, USER);
+  }
+
+  @Test
+  public void testUpdatePublicItemVersion() throws Exception {
+    testUpdateItemVersion(Space.PUBLIC, ZusammenPluginConstants.PUBLIC_SPACE);
+  }
+
+  @Test
+  public void testDeletePrivateItemVersion() throws Exception {
+    testDeleteItemVersion(Space.PRIVATE, USER);
+  }
+
+  @Test
+  public void testDeletePublicItemVersion() throws Exception {
+    testDeleteItemVersion(Space.PUBLIC, ZusammenPluginConstants.PUBLIC_SPACE);
+  }
+
+  @Test
+  public void testPublishItemVersionWhenNotDirty() throws Exception {
+    Id itemId = new Id();
+    ItemVersion version = TestUtils.createItemVersion(new Id(), null, "v1", false);
+    doReturn(Optional.of(version)).when(versionDaoMock).get(context, USER, itemId, version.getId());
+
+    versionCollaborationStore.publishItemVersion(context, itemId, version.getId(), "message");
+
+  }
+*//*
+  private void testIsItemVersionExist(Space space, String spaceName) {
+    Id itemId = new Id();
+    ItemVersion retrievedVersion = TestUtils.createItemVersion(new Id(), null, "v1");
+    doReturn(Optional.of(retrievedVersion)).when(versionDaoMock)
+        .get(context, spaceName, itemId, retrievedVersion.getId());
+
+    boolean itemExist =
+        versionCollaborationStore
+            .isItemVersionExist(context, space, itemId, retrievedVersion.getId());
+    Assert.assertTrue(itemExist);
+  }
+
+  private void testGetItemVersion(Space space, String spaceName) throws Exception {
+    Id itemId = new Id();
+    ItemVersion retrievedVersion = TestUtils.createItemVersion(new Id(), null, "v1");
+    doReturn(Optional.of(retrievedVersion)).when(versionDaoMock)
+        .get(context, spaceName, itemId, retrievedVersion.getId());
+
+    ItemVersion itemVersion =
+        versionCollaborationStore.getItemVersion(context, space, itemId, retrievedVersion.getId());
+    Assert.assertEquals(itemVersion, retrievedVersion);
+  }
+
+  private void testListItemVersions(Space space, String spaceName) {
+    Id itemId = new Id();
+    ItemVersion v1 = TestUtils.createItemVersion(new Id(), null, "v1");
+    ItemVersion v2 = TestUtils.createItemVersion(new Id(), v1.getId(), "v2");
+    ItemVersion v3 = TestUtils.createItemVersion(new Id(), v2.getId(), "v3");
+    List<ItemVersion> retrievedVersions = Arrays.asList(v1, v2, v3);
+    doReturn(retrievedVersions).when(versionDaoMock).list(context, spaceName, itemId);
+
+    Collection<ItemVersion> itemVersions =
+        versionCollaborationStore.listItemVersions(context, space, itemId);
+    Assert.assertEquals(itemVersions, retrievedVersions);
+  }*//*
+
+  private void testCreateItemVersion(Space space, String spaceName, Id baseId) {
+    Id itemId = new Id();
+    ItemVersion v1 = TestUtils.createItemVersion(new Id(), baseId, "v1", false);
+    List<ElementEntity> baseVersionElements = mockVersionElements(spaceName, itemId, baseId);
+
+    ArgumentCaptor<ItemVersion> versionCaptor = ArgumentCaptor.forClass(ItemVersion.class);
+
+    Date creationTime = new Date();
+    versionCollaborationStore
+        .createItemVersion(context, space, itemId, baseId, v1.getId(), v1.getData(), creationTime);
+
+    verify(versionDaoMock).create(eq(context), eq(spaceName), eq(itemId), versionCaptor.capture());
+    //baseId, v1.getId(),v1.getData(), creationTime);
+
+    ItemVersion capturedVersion = versionCaptor.getValue();
+    Assert.assertEquals(baseId, capturedVersion.getBaseId());
+    Assert.assertEquals(v1.getId(), capturedVersion.getId());
+    Assert.assertEquals(v1.getData(), capturedVersion.getData());
+    Assert.assertEquals(creationTime, capturedVersion.getCreationTime());
+*//*    verify(versionDaoMock)
+        .create(anyObject(), anyObject(), anyObject(), anyObject(), anyObject(), anyObject(),
+            anyObject());*//*
+
+*//*    if (baseId != null) {
+      baseVersionElements.forEach(element ->
+          verify(elementCollaborationStore).create(eq(context),
+              eq(new ElementEntityContext(spaceName, itemId, v1.getId())),
+              eq(element)));
+    } else {
+      verifyZeroInteractions(elementCollaborationStore);
+    }*//*
+  }
+
+  private void testUpdateItemVersion(Space space, String spaceName) {
+    Id itemId = new Id();
+    ItemVersion retrievedVersion = TestUtils.createItemVersion(new Id(), null, "v1", false);
+    doReturn(Optional.of(retrievedVersion)).when(versionDaoMock)
+        .get(context, spaceName, itemId, retrievedVersion.getId());
+
+    ItemVersionData updatedData = new ItemVersionData();
+    updatedData.setInfo(TestUtils.createInfo("v1 updated"));
+    updatedData.setRelations(
+        Arrays.asList(new Relation(), new Relation(), new Relation(), new Relation()));
+    versionCollaborationStore.updateItemVersion(
+        context, space, itemId, retrievedVersion.getId(), updatedData, new Date());
+
+    *//*verify(versionDaoMock)
+        .update(context, spaceName, itemId, retrievedVersion.getId(), updatedData, modificationTime);*//*
+    verify(versionDaoMock)
+        .update(anyObject(), anyObject(), anyObject(), anyObject());
+
+  }
+
+  private void testDeleteItemVersion(Space space, String spaceName) {
+    Id itemId = new Id();
+    Id versionId = new Id();
+
+    List<ElementEntity> versionElements = mockVersionElements(spaceName, itemId, versionId);
+    versionCollaborationStore.deleteItemVersion(context, space, itemId, versionId);
+
+*//*    versionElements.forEach(element ->
+        verify(elementCollaborationStore).delete(eq(context),
+            eq(new ElementEntityContext(spaceName, itemId, versionId)),
+            eq(element)));*//*
+    verify(versionDaoMock).delete(context, spaceName, itemId, versionId);
+  }
+
+  private List<ElementEntity> mockVersionElements(String spaceName, Id itemId, Id versionId) {
+    ElementEntity elm1 = new ElementEntity(new Id());
+    ElementEntity elm2 = new ElementEntity(new Id());
+    List<ElementEntity> baseVersionElements = Arrays.asList(elm1, elm2);
+*//*    doReturn(baseVersionElements).when(elementCollaborationStore)
+        .list(eq(context), eq(new ElementEntityContext(spaceName, itemId, versionId)));*//*
+    return baseVersionElements;
+  }*/
+}
\ No newline at end of file
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/test/java/org/openecomp/core/zusammen/plugin/collaboration/impl/ElementStageStoreImplTest.java b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/test/java/org/openecomp/core/zusammen/plugin/collaboration/impl/ElementStageStoreImplTest.java
new file mode 100644
index 0000000..7f137b0
--- /dev/null
+++ b/openecomp-be/lib/openecomp-core-lib/openecomp-zusammen-lib/openecomp-zusammen-plugin/src/test/java/org/openecomp/core/zusammen/plugin/collaboration/impl/ElementStageStoreImplTest.java
@@ -0,0 +1,167 @@
+package org.openecomp.core.zusammen.plugin.collaboration.impl;
+
+import com.amdocs.zusammen.datatypes.Id;
+import com.amdocs.zusammen.datatypes.SessionContext;
+import com.amdocs.zusammen.datatypes.UserInfo;
+import com.amdocs.zusammen.datatypes.item.Action;
+import com.amdocs.zusammen.datatypes.item.ElementContext;
+import com.amdocs.zusammen.datatypes.item.Resolution;
+import com.amdocs.zusammen.plugin.statestore.cassandra.dao.types.ElementEntityContext;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.Spy;
+import org.openecomp.core.zusammen.plugin.collaboration.TestUtils;
+import org.openecomp.core.zusammen.plugin.dao.ElementStageRepository;
+import org.openecomp.core.zusammen.plugin.dao.types.ElementEntity;
+import org.openecomp.core.zusammen.plugin.dao.types.StageEntity;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Optional;
+import java.util.Set;
+
+import static org.mockito.Matchers.anyObject;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.same;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class ElementStageStoreImplTest {
+  private static final UserInfo USER = new UserInfo("user");
+  private static final SessionContext context = TestUtils.createSessionContext(USER, "test");
+  private static final ElementContext elementContext =
+      TestUtils.createElementContext(new Id(), new Id());
+
+  @Mock
+  private ElementStageRepository elementStageRepositoryMock;
+  @Spy
+  private ElementStageStoreImpl elementStageStore;
+
+  @BeforeMethod
+  public void setUp() throws Exception {
+    MockitoAnnotations.initMocks(this);
+    when(elementStageStore.getElementStageRepository(anyObject()))
+        .thenReturn(elementStageRepositoryMock);
+  }
+
+  @Test
+  public void testListIds() throws Exception {
+
+  }
+
+  @Test
+  public void testGet() throws Exception {
+
+  }
+
+  @Test
+  public void testGetConflicted() throws Exception {
+
+  }
+
+  @Test
+  public void testHasConflicts() throws Exception {
+
+  }
+
+  @Test
+  public void testListConflictedDescriptors() throws Exception {
+
+  }
+
+  @Test
+  public void testCreate() throws Exception {
+
+  }
+
+  @Test
+  public void testDelete() throws Exception {
+
+  }
+
+  @Test
+  public void testResolveConflictWhenNotStaged() throws Exception {
+    doReturn(Optional.empty())
+        .when(elementStageRepositoryMock).get(anyObject(), anyObject(), anyObject());
+    elementStageStore
+        .resolveConflict(context, elementContext, new ElementEntity(new Id()), Resolution.YOURS);
+  }
+
+  @Test
+  public void testResolveConflictWhenNotConflicted() throws Exception {
+    Id elementId = new Id();
+    StageEntity<ElementEntity> stagedElement =
+        new StageEntity<>(new ElementEntity(elementId), new Date());
+    doReturn(Optional.of(stagedElement))
+        .when(elementStageRepositoryMock).get(anyObject(), anyObject(), anyObject());
+    elementStageStore
+        .resolveConflict(context, elementContext, new ElementEntity(elementId), Resolution.YOURS);
+  }
+
+  @Test
+  public void testResolveConflictByYours() throws Exception {
+    Id elementId = new Id();
+    StageEntity<ElementEntity> stagedElement =
+        new StageEntity<>(new ElementEntity(elementId), new Date());
+    stagedElement.setAction(Action.UPDATE);
+    stagedElement.setConflicted(true);
+
+    doReturn(Optional.of(stagedElement))
+        .when(elementStageRepositoryMock).get(anyObject(), anyObject(), anyObject());
+
+    elementStageStore
+        .resolveConflict(context, elementContext, new ElementEntity(elementId), Resolution.YOURS);
+
+    verify(elementStageRepositoryMock).markAsNotConflicted(same(context),
+        eq(new ElementEntityContext(USER.getUserName(), elementContext)),
+        same(stagedElement.getEntity()), same(Action.IGNORE));
+  }
+
+  @Test
+  public void testResolveConflictByYoursWithRelated() throws Exception {
+    Id elementId = new Id();
+    StageEntity<ElementEntity> stagedElement =
+        new StageEntity<>(new ElementEntity(elementId), new Date());
+    stagedElement.setAction(Action.UPDATE);
+    stagedElement.setConflicted(true);
+    ElementEntity relatedElement1 = new ElementEntity(new Id());
+    ElementEntity relatedElement2 = new ElementEntity(new Id());
+    ElementEntity relatedElement3 = new ElementEntity(new Id());
+    Set<ElementEntity> relatedElements = new HashSet<>();
+    relatedElements.add(relatedElement1);
+    relatedElements.add(relatedElement2);
+    relatedElements.add(relatedElement3);
+    stagedElement.setConflictDependents(relatedElements);
+
+    doReturn(Optional.of(stagedElement))
+        .when(elementStageRepositoryMock).get(anyObject(), anyObject(), anyObject());
+
+    elementStageStore
+        .resolveConflict(context, elementContext, new ElementEntity(elementId), Resolution.YOURS);
+
+    ElementEntityContext elementEntityContext =
+        new ElementEntityContext(USER.getUserName(), elementContext);
+    verify(elementStageRepositoryMock).markAsNotConflicted(same(context), eq(elementEntityContext),
+        same(stagedElement.getEntity()), same(Action.IGNORE));
+    verify(elementStageRepositoryMock).markAsNotConflicted(same(context), eq(elementEntityContext),
+        same(relatedElement1), same(Action.IGNORE));
+    verify(elementStageRepositoryMock).markAsNotConflicted(same(context), eq(elementEntityContext),
+        same(relatedElement2), same(Action.IGNORE));
+    verify(elementStageRepositoryMock).markAsNotConflicted(same(context), eq(elementEntityContext),
+        same(relatedElement3), same(Action.IGNORE));
+  }
+
+  @Test
+  public void testResolveConflictByTheirs() throws Exception {
+
+  }
+
+  @Test
+  public void testResolveConflictByTheirsWithRelated() throws Exception {
+
+  }
+
+}
\ No newline at end of file
diff --git a/openecomp-be/lib/openecomp-core-lib/pom.xml b/openecomp-be/lib/openecomp-core-lib/pom.xml
index 3784593..51faa10 100644
--- a/openecomp-be/lib/openecomp-core-lib/pom.xml
+++ b/openecomp-be/lib/openecomp-core-lib/pom.xml
@@ -20,5 +20,6 @@
         <module>/openecomp-utilities-lib</module>
         <module>/openecomp-config-lib</module>
         <module>/openecomp-zusammen-lib</module>
+        <module>/openecomp-session-lib</module>
     </modules>
 </project>